1 /** 2 AutoMapper naming convention. 3 4 You can create your own naming convetion by defining a struct with this shape: 5 6 ---- 7 struct MyConvention 8 { 9 string convert(string identifier) 10 { 11 ... 12 } 13 14 string convertBack(string myConvention) 15 { 16 ... 17 } 18 } 19 ---- 20 */ 21 module automapper.naming; 22 23 import automapper.meta; 24 25 /** 26 The camel case naming convetion. 27 */ 28 struct CamelCaseNamingConvention 29 { 30 /// Convert from foo.bar.baz to fooBarBaz 31 string convert(string flattened) 32 { 33 import std..string : split, join, capitalize; 34 import std.algorithm : map; 35 36 auto sp = flattened.split("."); 37 return sp[0] ~ sp[1..$].map!capitalize.join(); 38 } 39 40 /// Convert from fooBarBaz to foo.bar.baz 41 string convertBack(string camelCase) 42 { 43 import std..string : join; 44 45 return camelCase.splitOnCase().join("."); 46 } 47 } 48 49 /// 50 unittest 51 { 52 static assert(CamelCaseNamingConvention().convert("foo.bar.baz") == "fooBarBaz"); 53 static assert(CamelCaseNamingConvention().convertBack("fooBarBaz") == "foo.bar.baz"); 54 static assert(CamelCaseNamingConvention().convert("foo") == "foo"); 55 static assert(CamelCaseNamingConvention().convertBack("foo") == "foo"); 56 } 57 58 /** 59 The pascal case naming convetion. 60 */ 61 struct PascalCaseNamingConvention 62 { 63 /// Convert from foo.bar.baz to fooBarBaz 64 string convert(string flattened) 65 { 66 import std..string : split, join, capitalize; 67 import std.algorithm : map; 68 69 auto sp = flattened.split("."); 70 return sp.map!capitalize.join(); 71 } 72 73 /// Convert from fooBarBaz to foo.bar.baz 74 string convertBack(string pascalCase) 75 { 76 import std..string : join; 77 import std..string : toLower; 78 79 return pascalCase.splitOnCase().join(".").toLower(); 80 } 81 } 82 83 /// 84 unittest 85 { 86 static assert(PascalCaseNamingConvention().convert("foo.bar.baz") == "FooBarBaz"); 87 static assert(PascalCaseNamingConvention().convertBack("FooBarBaz") == "foo.bar.baz"); 88 static assert(PascalCaseNamingConvention().convert("foo") == "Foo"); 89 static assert(PascalCaseNamingConvention().convertBack("Foo") == "foo"); 90 } 91 92 /** 93 The lower undescore naming convetion. 94 */ 95 struct LowerUnderscoreNamingConvention 96 { 97 /// Convert from foo.bar.baz to fooBarBaz 98 string convert(string flattened) 99 { 100 import std..string : split, join, capitalize; 101 import std.algorithm : map; 102 103 return flattened.split(".").join("_"); 104 } 105 106 /// Convert from fooBarBaz to foo.bar.baz 107 string convertBack(string lowerUnder) 108 { 109 import std..string : split, join; 110 111 return lowerUnder.split("_").join("."); 112 } 113 } 114 115 /// 116 unittest 117 { 118 static assert(LowerUnderscoreNamingConvention().convert("foo.bar.baz") == "foo_bar_baz"); 119 static assert(LowerUnderscoreNamingConvention().convertBack("foo_bar_baz") == "foo.bar.baz"); 120 static assert(LowerUnderscoreNamingConvention().convert("foo") == "foo"); 121 static assert(LowerUnderscoreNamingConvention().convertBack("foo") == "foo"); 122 } 123 124 /// 125 template isNamingConvention(T) 126 { 127 enum isNamingConvention = ( 128 hasSpecifiedCallable!(T, "convert", string, string) && 129 hasSpecifiedCallable!(T, "convertBack", string, string)); 130 } 131 132 /// 133 unittest 134 { 135 static assert(isNamingConvention!CamelCaseNamingConvention); 136 }