1 module nxt.casing; 2 3 import std.traits : isSomeString; 4 5 version(unittest) 6 { 7 import std.algorithm : equal; 8 } 9 10 /** Convert string $(S s) to lower-case. 11 * 12 * String must contain ASCII characters only. 13 */ 14 auto toLowerASCII(S)(S s) 15 if (isSomeString!S) 16 { 17 import std.algorithm.iteration : map; 18 import std.ascii : toLower; 19 import std.traits : isNarrowString; 20 static if (isNarrowString!S) 21 { 22 import std.utf : byUTF; 23 return s.byUTF!dchar.map!(ch => ch.toLower); 24 } 25 else 26 return t.map!(ch => ch.toLower); 27 } 28 29 /// 30 @safe pure /*TODO: nothrow @nogc*/ unittest 31 { 32 assert("Lasse".toLowerASCII.equal("lasse")); 33 assert("Åberg".toLowerASCII.equal("Åberg")); // ignores unicode letters 34 } 35 36 /** Convert string $(S s) to lower-case. 37 * 38 * String may contain Unicode characters. 39 */ 40 auto toLowerUnicode(S)(S s) 41 if (isSomeString!S) 42 { 43 import std.algorithm.iteration : map; 44 import std.uni : toLower; 45 import std.traits : isNarrowString; 46 // TODO: functionize 47 static if (isNarrowString!S) 48 { 49 import std.utf : byUTF; 50 return s.byUTF!dchar.map!(ch => ch.toLower); 51 } 52 else 53 return t.map!(ch => ch.toLower); 54 } 55 56 /// 57 @safe pure /*TODO: nothrow @nogc*/ unittest 58 { 59 assert("Lasse".toLowerUnicode.equal("lasse")); 60 assert("Åberg".toLowerUnicode.equal("åberg")); 61 } 62 63 /** Convert D-style camel-cased string $(S s) to lower-cased words. 64 */ 65 auto camelCasedToLower(S)(S s) 66 if (isSomeString!S) 67 { 68 import std.algorithm.iteration : map; 69 import std.ascii : isUpper; // D symbol names can only be in ASCII 70 // TODO: Instead of this add std.ascii.as[Lower|Upper]Case and import std.ascii.asLowerCase 71 import std.uni : asLowerCase; 72 import nxt.slicing : preSlicer; 73 return s.preSlicer!isUpper.map!asLowerCase; 74 } 75 76 /// 77 @safe pure unittest 78 { 79 auto x = "doThis".camelCasedToLower; 80 assert(x.front.equal("do")); 81 x.popFront(); 82 assert(x.front.equal("this")); 83 } 84 85 /** Convert D-Style camel-cased string $(S s) to space-separated lower-cased words. 86 */ 87 auto camelCasedToLowerSpaced(S, Separator)(S s, const Separator separator = " ") 88 if (isSomeString!S) 89 { 90 import std.algorithm.iteration : joiner; 91 return camelCasedToLower(s).joiner(separator); 92 } 93 94 /// 95 @safe pure unittest 96 { 97 assert(equal("doThis".camelCasedToLowerSpaced, 98 "do this")); 99 } 100 101 /** Convert enumeration value (enumerator) $(D t) to a range chars. 102 */ 103 auto toLowerSpacedChars(T, Separator)(const T t, 104 const Separator separator = " ") 105 if (is(T == enum)) 106 { 107 import nxt.enum_ex : toStringFaster; 108 return t.toStringFaster 109 .camelCasedToLowerSpaced(separator); 110 } 111 112 /// 113 @safe pure unittest 114 { 115 enum Things { isUri, isLink } 116 assert(Things.isUri.toLowerSpacedChars.equal("is uri")); 117 assert(Things.isLink.toLowerSpacedChars.equal("is link")); 118 } 119 120 /// 121 @safe pure unittest 122 { 123 enum Things { isURI, isLink } 124 auto r = Things.isURI.toLowerSpacedChars; 125 alias R = typeof(r); 126 import std.range.primitives : ElementType; 127 alias E = ElementType!R; 128 static assert(is(E == dchar)); 129 }