1 /++ 2 String manipulation utilities needed by Godot-D 3 +/ 4 module godotutil..string; 5 6 import std..string, std.uni, std.utf; 7 import std.range, std.traits; 8 9 /++ 10 Convert snake_case or CONSTANT_CASE to D-style camelCase. 11 12 Preserves leading underscore. 13 +/ 14 nothrow 15 T snakeToCamel(T)(in T inputStr) if(isSomeString!T) 16 { 17 Unqual!T str = inputStr; 18 alias Char = Unqual!(ElementEncodingType!T); 19 Char[] ret = []; 20 21 bool newWord = false; 22 while(!str.empty) 23 { 24 dchar c = str.decodeFront!(Yes.useReplacementDchar, Unqual!T); 25 if(c == '_') 26 { 27 if(ret.empty) ret.encode!(Yes.useReplacementDchar)('_'); 28 else newWord = true; 29 } 30 else 31 { 32 if(newWord) 33 { 34 ret.encode!(Yes.useReplacementDchar)(c.toUpper); 35 newWord = false; 36 } 37 else ret.encode!(Yes.useReplacementDchar)(c.toLower); 38 } 39 } 40 return ret; 41 } 42 43 static assert("snake_case".snakeToCamel == "snakeCase"); 44 static assert("_physics_process".snakeToCamel == "_physicsProcess", "_physics_process".snakeToCamel); 45 static assert("CONSTANT_CASE".snakeToCamel == "constantCase"); 46 47 /++ 48 Convert camelCase to Godot-style snake_case. 49 50 Preserves leading underscore. 51 +/ 52 nothrow 53 T camelToSnake(T)(in T inputStr) if(isSomeString!T) 54 { 55 Unqual!T str = inputStr; 56 alias Char = Unqual!(ElementEncodingType!T); 57 Char[] ret = []; 58 59 bool inUppercaseWord = false; 60 while(!str.empty) 61 { 62 dchar c = str.decodeFront!(Yes.useReplacementDchar); 63 if(c.isUpper) 64 { 65 if(!ret.empty && !inUppercaseWord) ret.encode!(Yes.useReplacementDchar)('_'); 66 ret.encode!(Yes.useReplacementDchar)(c.toLower); 67 inUppercaseWord = true; 68 } 69 else 70 { 71 ret.encode!(Yes.useReplacementDchar)(c); 72 inUppercaseWord = false; 73 } 74 } 75 return ret; 76 } 77 78 static assert("camelCase".camelToSnake == "camel_case"); 79 static assert("_physicsProcess".camelToSnake == "_physics_process"); 80 static assert("toUTF32".camelToSnake == "to_utf32"); 81