1 /**
2 * Copyright © DiamondMVC 2019
3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE)
4 * Author: Jacob Jensen (bausshf)
5 */
6 module diamond.core..string;
7 
8 import std.traits : isSomeString;
9 
10 /**
11 * Converts the first character of a string to lowercase.
12 * Params:
13 *   s = The string to lowercase the first character.
14 * Returns:
15 *   Returns a new string with the first character lowercased. The string is returned unmodified if its null or empty.
16 */
17 TString firstToLower(TString)(TString s)
18 if (isSomeString!TString)
19 {
20   import std..string : toLower;
21   import std.conv : to;
22 
23   if (!s || !s.length)
24   {
25     return s;
26   }
27 
28   if (s.length == 1)
29   {
30     return s.toLower();
31   }
32 
33   return to!string(s[0]).toLower() ~ s[1 .. $];
34 }
35 
36 /**
37 * Converts the first character of a string to uppercase.
38 * Params:
39 *   s = The string to uppercase the first character.
40 * Returns:
41 *   Returns a new string with the first character uppercased. The string is returned unmodified if its null or empty.
42 */
43 TString firstToUpper(TString)(TString s)
44 if (isSomeString!TString)
45 {
46   import std..string : toUpper;
47   import std.conv : to;
48 
49   if (!s || !s.length)
50   {
51     return s;
52   }
53 
54   if (s.length == 1)
55   {
56     return s.toUpper();
57   }
58 
59   return to!string(s[0]).toUpper() ~ s[1 .. $];
60 }
61 
62 /**
63 * Splits a string input into grouped words.
64 * Params:
65 *   input = The input to split into grouped words.
66 * Returns:
67 *   The string split into grouped words.
68 */
69 string[] splitIntoGroupedWords(string input)
70 {
71   import std.array : split;
72 
73   auto inputs = input.split(" ");
74   string[] words = [];
75 
76   foreach (i; 0 .. inputs.length)
77   {
78     string current = inputs[i];
79     string next1 = i < (inputs.length - 1) ? (" " ~ inputs[i + 1]) : null;
80     string next2 = i < (inputs.length - 2) ? (" " ~ inputs[i + 2]) : null;
81 
82     words ~= current;
83 
84     if (next1)
85     {
86       words ~= current ~ next1;
87     }
88 
89     if (next2)
90     {
91       words ~= current ~ next1 ~ next2;
92     }
93   }
94 
95   return words;
96 }