1 /** 2 AutoMapper API. 3 4 This module is the entry point for building an AutoMapper configuration. 5 */ 6 module automapper.api; 7 8 import automapper.meta; 9 import automapper.naming; 10 public import automapper.config; 11 12 13 /// Entry point for building an object mapper configuration in a fluent way 14 class CreateMap(TSource, TDest, Configs...) : ObjectMapperConfig!(TSource, TDest, 15 findOrDefault!(isSourceNamingConventionConfig, 16 SourceNamingConventionConfig!CamelCaseNamingConvention, Configs) 17 .Convention, 18 findOrDefault!(isDestNamingConventionConfig, 19 DestNamingConventionConfig!CamelCaseNamingConvention, Configs) 20 .Convention, 21 onlyOneExists!(isReverseMapConfig, Configs), 22 Filter!(isObjectMemberMappingConfig, Configs)) 23 if (isClassOrStruct!TSource && isClassOrStruct!TDest) 24 { 25 /// Tell to reverse the mapper automatically 26 template ReverseMap() 27 { 28 alias ReverseMap = CreateMap!(TSource, TDest, AliasSeq!(Configs, ReverseMapConfig)); 29 } 30 31 /// Precise a member mapping 32 template ForMember(string DestMember, string SrcMember) 33 { 34 alias ForMember = CreateMap!(TSource, TDest, AliasSeq!(Configs, 35 ForMemberConfig!(DestMember, SrcMember))); 36 } 37 38 /// Customize member mapping with a delegate 39 template ForMember(string DestMember, alias Delegate) 40 { 41 alias ForMember = CreateMap!(TSource, TDest, AliasSeq!(Configs, 42 ForMemberConfig!(DestMember, Delegate))); 43 } 44 45 /// Ignore a member 46 template Ignore(string DestMember) 47 { 48 alias Ignore = CreateMap!(TSource, TDest, AliasSeq!(Configs, IgnoreConfig!DestMember)); 49 } 50 51 /// Set source naming convention 52 template SourceMemberNaming(TConv) if (isNamingConvention!TConv) 53 { 54 alias SourceMemberNaming = CreateMap!(TSource, TDest, AliasSeq!(Configs, SourceNamingConventionConfig!TConv)); 55 } 56 57 /// Set dest. naming convention 58 template DestMemberNaming(TConv) if (isNamingConvention!TConv) 59 { 60 alias DestMemberNaming = CreateMap!(TSource, TDest, AliasSeq!(Configs, DestNamingConventionConfig!TConv)); 61 } 62 } 63 64 /// 65 unittest 66 { 67 import automapper : MapperConfiguration, CreateMap; 68 69 static class A { 70 string foo; 71 int bar; 72 } 73 74 static class B { 75 string qux; 76 int baz; 77 } 78 79 MapperConfiguration!( 80 CreateMap!(A, B) 81 .ForMember!("qux", "foo") 82 .ForMember!("baz", "foo")) 83 .createMapper(); 84 } 85 86 /// 87 88 89 90 91 /// entry point for bulding a type converter configuration 92 class CreateMap(A, B) if (!isClassOrStruct!A || !isClassOrStruct!B) 93 { 94 import automapper.type.converter : DelegateTypeConverter, isTypeConverter; 95 96 /// 97 static class ConvertUsing(alias Delegate) : DelegateTypeConverter!(A, B, Delegate) if (isCallable!Delegate) 98 { 99 static assert(is(ReturnType!Delegate == B), "must return a " ~ B.stringof); 100 static assert((Parameters!Delegate.length == 1) && is(Parameters!Delegate[0] == A), 101 "must take one argument of type " ~ A.stringof); 102 } 103 104 /// 105 template ConvertUsing(Type) if (isTypeConverter!Type) 106 { 107 alias ConvertUsing = Type; 108 } 109 } 110 111 112 /// 113 unittest 114 { 115 import automapper; 116 import std.datetime : SysTime; 117 118 static class A { 119 long timestamp; 120 } 121 122 static class B { 123 SysTime timestamp; 124 } 125 126 MapperConfiguration!( 127 CreateMap!(long, SysTime) 128 .ConvertUsing!((long ts) => SysTime(ts)), 129 CreateMap!(A, B)) 130 .createMapper(); 131 }