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