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 }