1 //Written in the D programming language
2 /*
3  * String utilities
4  *
5  * Copyright 2013 Jaypha.
6  *
7  * Distributed under the Boost Software License, Version 1.0.
8  * (See http://www.boost.org/LICENSE_1_0.txt)
9  *
10  * Authors: Jason den Dulk
11  */
12 
13 module jaypha..string;
14 
15 import std.string;
16 import std.uni;
17 import std.array;
18 import core.stdc.string;
19 
20 //-----------------------------------------------------------------------------
21 // A quick and dirty alternative indexOf. Only works with ASCII.
22 
23 size_t altIndexOf(string s, char c)
24 {
25   auto p = cast(char*)memchr(s.ptr, c, s.length);
26   return (p?p - s.ptr:s.length);
27 }
28 
29 //----------------------------------------------------------------------------
30 // Are all characters digits?
31 
32 @safe pure nothrow bool isDigits(string text)
33 {
34   import std.ascii;
35 
36   foreach (c; text)
37     if (!isDigit(c))
38       return false;
39   return true;
40 }
41 
42 //----------------------------------------------------------------------------
43 // Splits a string into substrings based on a group of possible delimiters.
44 
45 string[] splitUp(string text, const(char)[] delimiters)
46 {
47   string[] result = [];
48   size_t start = 0;
49 
50   foreach(i; 0..text.length)
51     if (indexOf(delimiters, text[i]) != -1)
52     {
53       result ~= text[start..i];
54       start = i+1;
55     }
56   result ~= text[start..$];
57 
58   return result;
59 }
60 
61 //----------------------------------------------------------------------------
62 // Converts a string to camel case.
63 
64 @trusted pure string toCamelCase(string text, bool first = true)
65 {
66   auto result = appender!string();
67 
68   foreach (ch; text)
69   {
70     if (ch == '_' || ch == ' ')
71     {
72       first = true;
73     }
74     else if (first)
75     {
76       result.put(toUpper(ch));
77       first = false;
78     }
79     else
80     {
81       result.put(ch);
82     }
83   }
84   return result.data;
85 }
86 
87 //----------------------------------------------------------------------------
88 
89 unittest
90 {
91   assert(toCamelCase("abc_def pip") == "AbcDefPip");
92   assert(toCamelCase("xyz_tob", false) == "xyzTob");
93   assert(toCamelCase("123_456", false) == "123456");
94 
95   auto result = splitUp("to be or not to be", " e");
96   assert(result.length == 8);
97   assert(result[0] == "to");
98   assert(result[1] == "b");
99   assert(result[2] == "");
100   assert(result[3] == "or");
101   assert(result[4] == "not");
102   assert(result[5] == "to");
103   assert(result[6] == "b");
104   assert(result[7] == "");
105 
106   auto t1 = "abcdefghijklmnop";
107   assert(altIndexOf(t1,'f') == 5);
108   assert(altIndexOf(t1,'a') == 0);
109   assert(altIndexOf(t1,'$') == t1.length);
110 
111   assert(isDigits("02351"));
112   assert(!isDigits("0x03"));
113   assert(!isDigits("-1"));
114   assert(!isDigits("1-"));
115 }