replaceRandom

Replaces $random and $random(i..n) tokens in a string with corresponding random values.

If given only $random, a value between the passed defaultLowerBound inclusive to defaultUpperBound exclusive is substituted, whereas if a range of $random(i..n) is given, a value between i inclusive and n exclusive is substituted.

On syntax errors, or if n is not greater than i, the original line is silently returned.

@safe
replaceRandom
(
const string line
,
const long defaultLowerBound = 0
,
const long defaultUpperBound = 100
)

Parameters

line string

String to replace tokens in.

defaultLowerBound long

Default lower bound when no range given.

defaultUpperBound long

Default upper bound when no range given.

Return Value

Type: auto

A new string with occurrences of $random and $random(i..n) replaced, or the original string if there were no changes made.

Examples

1 import lu.string : advancePast, splitInto;
2 import std.conv : to;
3 
4 {
5     enum line = "$random bottles of beer on the wall";
6     string replaced = line.replaceRandom();  // mutable
7     immutable number = replaced.advancePast(' ').to!int;
8     assert(((number >= 0) && (number < 100)), number.to!string);
9 }
10 {
11     enum line = "$random(100..200) bottles of beer on the wall";
12     string replaced = line.replaceRandom();  // mutable
13     immutable number = replaced.advancePast(' ').to!int;
14     assert(((number >= 100) && (number < 200)), number.to!string);
15 }
16 {
17     enum line = "$random(-20..-10) bottles of beer on the wall";
18     string replaced = line.replaceRandom();  // mutable
19     immutable number = replaced.advancePast(' ').to!int;
20     assert(((number >= -20) && (number < -10)), number.to!string);
21 }
22 /*{
23     static if (__VERSION__ > 2089L)
24     {
25         // Fails pre-2.090 with Error: signed integer overflow
26         enum line = "$random(-9223372036854775808..9223372036854775807) bottles of beer on the wall";
27         string replaced = line.replaceRandom();  // mutable
28         immutable number = replaced.advancePast(' ').to!long;
29         //assert(((number >= cast(long)-9223372036854775808) && (number < 9223372036854775807)), number.to!string);
30     }
31 }*/
32 {
33     // syntax error, no bounds given
34     enum line = "$random() bottles of beer on the wall";
35     immutable replaced = line.replaceRandom();
36     assert((replaced == line), replaced);
37 }
38 {
39     // syntax error, no closing paren
40     enum line = "$random( bottles of beer on the wall";
41     immutable replaced = line.replaceRandom();
42     assert((replaced == line), replaced);
43 }
44 {
45     // syntax error, no upper bound given
46     enum line = "$random(0..) bottles of beer on the wall";
47     immutable replaced = line.replaceRandom();
48     assert((replaced == line), replaced);
49 }
50 {
51     // syntax error, no bounds given
52     enum line = "$random(..) bottles of beer on the wall";
53     immutable replaced = line.replaceRandom();
54     assert((replaced == line), replaced);
55 }
56 {
57     // syntax error, invalid bounds
58     enum line = "$random(X.....Y) bottles of beer on the wall";
59     immutable replaced = line.replaceRandom();
60     assert((replaced == line), replaced);
61 }
62 {
63     // syntax error, missing closing paren
64     enum line = "$random(0..100 bottles of beer on the wall";
65     immutable replaced = line.replaceRandom();
66     assert((replaced == line), replaced);
67 }
68 {
69     // syntax error, parens include text
70     enum line = "$random(0..100 bottles of beer on the wall)";
71     immutable replaced = line.replaceRandom();
72     assert((replaced == line), replaced);
73 }
74 {
75     // syntax error, i == n
76     enum line = "$random(0..0) bottles of beer on the wall";
77     immutable replaced = line.replaceRandom();
78     assert((replaced == line), replaced);
79 }
80 {
81     // syntax error, i > n
82     enum line = "$random(2..1) bottles of beer on the wall";
83     immutable replaced = line.replaceRandom();
84     assert((replaced == line), replaced);
85 }
86 {
87     // partly syntax error
88     enum line = "blerp $random(50..55) $random(2..1) $random blarp";
89     immutable replaced = line.replaceRandom();
90     string slice = replaced;  // mutable
91     string blerp, n1s, syntaxError, n2s, blarp;
92     slice.splitInto(blerp, n1s, syntaxError, n2s, blarp);
93     immutable n1 = n1s.to!int;
94     immutable n2 = n2s.to!int;
95     assert((blerp == "blerp"), blerp);
96     assert((n1 >= 50 && n1 < 55), n1.to!string);
97     assert((syntaxError == "$random(2..1)"), syntaxError);
98     assert((n2 >= 0 && n2 < 100), n2.to!string);
99     assert((blarp == "blarp"), blarp);
100 }
101 {
102     // empty string
103     enum line = string.init;
104     string replaced = line.replaceRandom();
105     assert(!replaced.length, replaced);
106 }
107 {
108     // no $random token
109     enum line = "99 bottles of beer on the wall";
110     immutable replaced = line.replaceRandom();
111     assert((replaced == line), replaced);
112 }
113 {
114     // multiple tokens
115     enum line = "$random(1..100) $random(101..200) $random(201..300)";
116     immutable replaced = line.replaceRandom();
117     string slice = replaced;  // mutable
118     string n1s, n2s, n3s;
119     slice.splitInto(n1s, n2s, n3s);
120     immutable n1 = n1s.to!int;
121     immutable n2 = n2s.to!int;
122     immutable n3 = n3s.to!int;
123     assert((n1 >= 1 && n1 < 100), n1.to!string);
124     assert((n2 >= 101 && n2 < 200), n2.to!string);
125     assert((n3 >= 201 && n3 < 300), n3.to!string);
126 }
127 {
128     // multiple tokens with other text
129     enum line = "$random $randomz $random gau gau";
130     immutable replaced = line.replaceRandom();
131     string slice = replaced;  // mutable
132     string n1s, n2z, n3s;
133     slice.splitInto(n1s, n2z, n3s);
134     immutable n1 = n1s.to!int;
135     immutable n2 = n2z[0..$-1].to!int;
136     immutable n3 = n3s.to!int;
137     immutable z = n2z[$-1..$];
138     assert((n1 >= 0 && n1 < 100), n1.to!string);
139     assert((n2 >= 0 && n2 < 100), n1.to!string);
140     assert((n3 >= 0 && n3 < 100), n3.to!string);
141     assert((z == "z"), z);
142     assert((slice == "gau gau"), slice);
143 }
144 {
145     // multiple tokens with other text again
146     enum line = "$random, $random! $random?";
147     immutable replaced = line.replaceRandom();
148     string slice = replaced;  // mutable
149     string n1comma, n2excl, n3question;
150     slice.splitInto(n1comma, n2excl, n3question);
151     immutable n1 = n1comma[0..$-1].to!int;
152     immutable comma = n1comma[$-1..$];
153     immutable n2 = n2excl[0..$-1].to!int;
154     immutable excl = n2excl[$-1..$];
155     immutable n3 = n3question[0..$-1].to!int;
156     immutable question = n3question[$-1..$];
157     assert((n1 >= 0 && n1 < 100), n1.to!string);
158     assert((n2 >= 0 && n2 < 100), n1.to!string);
159     assert((n3 >= 0 && n3 < 100), n3.to!string);
160     assert((comma == ","), comma);
161     assert((excl == "!"), excl);
162     assert((question == "?"), question);
163 }