ic-mops 0.8.5 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/package.json +3 -1
  2. package/.mops/base@0.7.4/LICENSE +0 -208
  3. package/.mops/base@0.7.4/README.md +0 -64
  4. package/.mops/base@0.7.4/mops.toml +0 -5
  5. package/.mops/base@0.7.4/src/Array.mo +0 -686
  6. package/.mops/base@0.7.4/src/AssocList.mo +0 -203
  7. package/.mops/base@0.7.4/src/Blob.mo +0 -55
  8. package/.mops/base@0.7.4/src/Bool.mo +0 -44
  9. package/.mops/base@0.7.4/src/Buffer.mo +0 -1937
  10. package/.mops/base@0.7.4/src/CertifiedData.mo +0 -29
  11. package/.mops/base@0.7.4/src/Char.mo +0 -67
  12. package/.mops/base@0.7.4/src/Debug.mo +0 -15
  13. package/.mops/base@0.7.4/src/Deque.mo +0 -75
  14. package/.mops/base@0.7.4/src/Error.mo +0 -41
  15. package/.mops/base@0.7.4/src/ExperimentalCycles.mo +0 -51
  16. package/.mops/base@0.7.4/src/ExperimentalInternetComputer.mo +0 -36
  17. package/.mops/base@0.7.4/src/ExperimentalStableMemory.mo +0 -121
  18. package/.mops/base@0.7.4/src/Float.mo +0 -150
  19. package/.mops/base@0.7.4/src/Func.mo +0 -38
  20. package/.mops/base@0.7.4/src/Hash.mo +0 -83
  21. package/.mops/base@0.7.4/src/HashMap.mo +0 -229
  22. package/.mops/base@0.7.4/src/Heap.mo +0 -113
  23. package/.mops/base@0.7.4/src/Int.mo +0 -150
  24. package/.mops/base@0.7.4/src/Int16.mo +0 -159
  25. package/.mops/base@0.7.4/src/Int32.mo +0 -160
  26. package/.mops/base@0.7.4/src/Int64.mo +0 -161
  27. package/.mops/base@0.7.4/src/Int8.mo +0 -160
  28. package/.mops/base@0.7.4/src/Iter.mo +0 -220
  29. package/.mops/base@0.7.4/src/IterType.mo +0 -7
  30. package/.mops/base@0.7.4/src/List.mo +0 -433
  31. package/.mops/base@0.7.4/src/Nat.mo +0 -75
  32. package/.mops/base@0.7.4/src/Nat16.mo +0 -146
  33. package/.mops/base@0.7.4/src/Nat32.mo +0 -146
  34. package/.mops/base@0.7.4/src/Nat64.mo +0 -146
  35. package/.mops/base@0.7.4/src/Nat8.mo +0 -146
  36. package/.mops/base@0.7.4/src/None.mo +0 -19
  37. package/.mops/base@0.7.4/src/Option.mo +0 -160
  38. package/.mops/base@0.7.4/src/Order.mo +0 -46
  39. package/.mops/base@0.7.4/src/Prelude.mo +0 -33
  40. package/.mops/base@0.7.4/src/Principal.mo +0 -58
  41. package/.mops/base@0.7.4/src/RBTree.mo +0 -218
  42. package/.mops/base@0.7.4/src/Random.mo +0 -188
  43. package/.mops/base@0.7.4/src/Result.mo +0 -210
  44. package/.mops/base@0.7.4/src/Stack.mo +0 -40
  45. package/.mops/base@0.7.4/src/Text.mo +0 -615
  46. package/.mops/base@0.7.4/src/Time.mo +0 -37
  47. package/.mops/base@0.7.4/src/Trie.mo +0 -1200
  48. package/.mops/base@0.7.4/src/TrieMap.mo +0 -180
  49. package/.mops/base@0.7.4/src/TrieSet.mo +0 -97
  50. package/.mops/base@0.8.3/LICENSE +0 -208
  51. package/.mops/base@0.8.3/README.md +0 -64
  52. package/.mops/base@0.8.3/mops.toml +0 -6
  53. package/.mops/base@0.8.3/src/Array.mo +0 -717
  54. package/.mops/base@0.8.3/src/AssocList.mo +0 -404
  55. package/.mops/base@0.8.3/src/Blob.mo +0 -212
  56. package/.mops/base@0.8.3/src/Bool.mo +0 -44
  57. package/.mops/base@0.8.3/src/Buffer.mo +0 -2660
  58. package/.mops/base@0.8.3/src/CertifiedData.mo +0 -53
  59. package/.mops/base@0.8.3/src/Char.mo +0 -65
  60. package/.mops/base@0.8.3/src/Debug.mo +0 -56
  61. package/.mops/base@0.8.3/src/Deque.mo +0 -243
  62. package/.mops/base@0.8.3/src/Error.mo +0 -68
  63. package/.mops/base@0.8.3/src/ExperimentalCycles.mo +0 -151
  64. package/.mops/base@0.8.3/src/ExperimentalInternetComputer.mo +0 -60
  65. package/.mops/base@0.8.3/src/ExperimentalStableMemory.mo +0 -348
  66. package/.mops/base@0.8.3/src/Float.mo +0 -843
  67. package/.mops/base@0.8.3/src/Func.mo +0 -46
  68. package/.mops/base@0.8.3/src/Hash.mo +0 -82
  69. package/.mops/base@0.8.3/src/HashMap.mo +0 -457
  70. package/.mops/base@0.8.3/src/Heap.mo +0 -233
  71. package/.mops/base@0.8.3/src/Int.mo +0 -365
  72. package/.mops/base@0.8.3/src/Int16.mo +0 -521
  73. package/.mops/base@0.8.3/src/Int32.mo +0 -522
  74. package/.mops/base@0.8.3/src/Int64.mo +0 -522
  75. package/.mops/base@0.8.3/src/Int8.mo +0 -522
  76. package/.mops/base@0.8.3/src/Iter.mo +0 -227
  77. package/.mops/base@0.8.3/src/IterType.mo +0 -7
  78. package/.mops/base@0.8.3/src/List.mo +0 -930
  79. package/.mops/base@0.8.3/src/Nat.mo +0 -305
  80. package/.mops/base@0.8.3/src/Nat16.mo +0 -144
  81. package/.mops/base@0.8.3/src/Nat32.mo +0 -144
  82. package/.mops/base@0.8.3/src/Nat64.mo +0 -144
  83. package/.mops/base@0.8.3/src/Nat8.mo +0 -144
  84. package/.mops/base@0.8.3/src/None.mo +0 -19
  85. package/.mops/base@0.8.3/src/Option.mo +0 -154
  86. package/.mops/base@0.8.3/src/Order.mo +0 -46
  87. package/.mops/base@0.8.3/src/Prelude.mo +0 -33
  88. package/.mops/base@0.8.3/src/Principal.mo +0 -249
  89. package/.mops/base@0.8.3/src/RBTree.mo +0 -681
  90. package/.mops/base@0.8.3/src/Random.mo +0 -270
  91. package/.mops/base@0.8.3/src/Result.mo +0 -209
  92. package/.mops/base@0.8.3/src/Stack.mo +0 -93
  93. package/.mops/base@0.8.3/src/Text.mo +0 -761
  94. package/.mops/base@0.8.3/src/Time.mo +0 -36
  95. package/.mops/base@0.8.3/src/Timer.mo +0 -62
  96. package/.mops/base@0.8.3/src/Trie.mo +0 -1603
  97. package/.mops/base@0.8.3/src/TrieMap.mo +0 -392
  98. package/.mops/base@0.8.3/src/TrieSet.mo +0 -148
  99. package/network.txt +0 -1
@@ -1,761 +0,0 @@
1
- /// Utility functions for `Text` values.
2
- ///
3
- /// A `Text` value represents human-readable text as a sequence of characters of type `Char`.
4
- ///
5
- /// ```motoko
6
- /// let text = "Hello!";
7
- /// let size = text.size(); // 6
8
- /// let iter = text.chars(); // iterator ('H', 'e', 'l', 'l', 'o', '!')
9
- /// let concat = text # " 👋"; // "Hello! 👋"
10
- /// ```
11
- ///
12
- /// The `"mo:base/Text"` module defines additional operations on `Text` values.
13
- ///
14
- /// Import the module from the base library:
15
- ///
16
- /// ```motoko name=import
17
- /// import Text "mo:base/Text";
18
- /// ```
19
- ///
20
- /// Note: `Text` values are represented as ropes of UTF-8 character sequences with O(1) concatenation.
21
- ///
22
-
23
- import Char "Char";
24
- import Iter "Iter";
25
- import Hash "Hash";
26
- import Stack "Stack";
27
- import Prim "mo:⛔";
28
-
29
- module {
30
-
31
- /// The type corresponding to primitive `Text` values.
32
- ///
33
- /// ```motoko
34
- /// let hello = "Hello!";
35
- /// let emoji = "👋";
36
- /// let concat = hello # " " # emoji; // "Hello! 👋"
37
- /// ```
38
- public type Text = Prim.Types.Text;
39
-
40
- /// Converts the given `Char` to a `Text` value.
41
- ///
42
- /// ```motoko include=import
43
- /// let text = Text.fromChar('A'); // "A"
44
- /// ```
45
- public let fromChar : (c : Char) -> Text = Prim.charToText;
46
-
47
- /// Iterates over each `Char` value in the given `Text`.
48
- ///
49
- /// Equivalent to calling the `t.chars()` method where `t` is a `Text` value.
50
- ///
51
- /// ```motoko include=import
52
- /// import { print } "mo:base/Debug";
53
- ///
54
- /// for (c in Text.toIter("abc")) {
55
- /// print(debug_show c);
56
- /// }
57
- /// ```
58
- public func toIter(t : Text) : Iter.Iter<Char> = t.chars();
59
-
60
- /// Creates a `Text` value from a `Char` iterator.
61
- ///
62
- /// ```motoko include=import
63
- /// let text = Text.fromIter(['a', 'b', 'c'].vals()); // "abc"
64
- /// ```
65
- public func fromIter(cs : Iter.Iter<Char>) : Text {
66
- var r = "";
67
- for (c in cs) {
68
- r #= Prim.charToText(c)
69
- };
70
- return r
71
- };
72
-
73
- /// Returns the number of characters in the given `Text`.
74
- ///
75
- /// Equivalent to calling `t.size()` where `t` is a `Text` value.
76
- ///
77
- /// ```motoko include=import
78
- /// let size = Text.size("abc"); // 3
79
- /// ```
80
- public func size(t : Text) : Nat { t.size() };
81
-
82
- /// Returns a hash obtained by using the `djb2` algorithm ([more details](http://www.cse.yorku.ca/~oz/hash.html)).
83
- ///
84
- /// ```motoko include=import
85
- /// let hash = Text.hash("abc");
86
- /// ```
87
- ///
88
- /// Note: this algorithm is intended for use in data structures rather than as a cryptographic hash function.
89
- public func hash(t : Text) : Hash.Hash {
90
- var x : Nat32 = 5381;
91
- for (char in t.chars()) {
92
- let c : Nat32 = Prim.charToNat32(char);
93
- x := ((x << 5) +% x) +% c
94
- };
95
- return x
96
- };
97
-
98
- /// Returns `t1 # t2`, where `#` is the `Text` concatenation operator.
99
- ///
100
- /// ```motoko include=import
101
- /// let a = "Hello";
102
- /// let b = "There";
103
- /// let together = a # b; // "HelloThere"
104
- /// let withSpace = a # " " # b; // "Hello There"
105
- /// let togetherAgain = Text.concat(a, b); // "HelloThere"
106
- /// ```
107
- public func concat(t1 : Text, t2 : Text) : Text = t1 # t2;
108
-
109
- /// Returns `t1 == t2`.
110
- public func equal(t1 : Text, t2 : Text) : Bool { t1 == t2 };
111
-
112
- /// Returns `t1 != t2`.
113
- public func notEqual(t1 : Text, t2 : Text) : Bool { t1 != t2 };
114
-
115
- /// Returns `t1 < t2`.
116
- public func less(t1 : Text, t2 : Text) : Bool { t1 < t2 };
117
-
118
- /// Returns `t1 <= t2`.
119
- public func lessOrEqual(t1 : Text, t2 : Text) : Bool { t1 <= t2 };
120
-
121
- /// Returns `t1 > t2`.
122
- public func greater(t1 : Text, t2 : Text) : Bool { t1 > t2 };
123
-
124
- /// Returns `t1 >= t2`.
125
- public func greaterOrEqual(t1 : Text, t2 : Text) : Bool { t1 >= t2 };
126
-
127
- /// Compares `t1` and `t2` lexicographically.
128
- ///
129
- /// ```motoko include=import
130
- /// import { print } "mo:base/Debug";
131
- ///
132
- /// print(debug_show Text.compare("abc", "abc")); // #equal
133
- /// print(debug_show Text.compare("abc", "def")); // #less
134
- /// print(debug_show Text.compare("abc", "ABC")); // #greater
135
- /// ```
136
- public func compare(t1 : Text, t2 : Text) : { #less; #equal; #greater } {
137
- let c = Prim.textCompare(t1, t2);
138
- if (c < 0) #less else if (c == 0) #equal else #greater
139
- };
140
-
141
- private func extract(t : Text, i : Nat, j : Nat) : Text {
142
- let size = t.size();
143
- if (i == 0 and j == size) return t;
144
- assert (j <= size);
145
- let cs = t.chars();
146
- var r = "";
147
- var n = i;
148
- while (n > 0) {
149
- ignore cs.next();
150
- n -= 1
151
- };
152
- n := j;
153
- while (n > 0) {
154
- switch (cs.next()) {
155
- case null { assert false };
156
- case (?c) { r #= Prim.charToText(c) }
157
- };
158
- n -= 1
159
- };
160
- return r
161
- };
162
-
163
- /// Join an iterator of `Text` values with a given delimiter.
164
- ///
165
- /// ```motoko include=import
166
- /// let joined = Text.join(", ", ["a", "b", "c"].vals()); // "a, b, c"
167
- /// ```
168
- public func join(sep : Text, ts : Iter.Iter<Text>) : Text {
169
- var r = "";
170
- if (sep.size() == 0) {
171
- for (t in ts) {
172
- r #= t
173
- };
174
- return r
175
- };
176
- let next = ts.next;
177
- switch (next()) {
178
- case null { return r };
179
- case (?t) {
180
- r #= t
181
- }
182
- };
183
- loop {
184
- switch (next()) {
185
- case null { return r };
186
- case (?t) {
187
- r #= sep;
188
- r #= t
189
- }
190
- }
191
- }
192
- };
193
-
194
- /// Applies a function to each character in a `Text` value, returning the concatenated `Char` results.
195
- ///
196
- /// ```motoko include=import
197
- /// // Replace all occurrences of '?' with '!'
198
- /// let result = Text.map("Motoko?", func(c) {
199
- /// if (c == '?') '!'
200
- /// else c
201
- /// });
202
- /// ```
203
- public func map(t : Text, f : Char -> Char) : Text {
204
- var r = "";
205
- for (c in t.chars()) {
206
- r #= Prim.charToText(f(c))
207
- };
208
- return r
209
- };
210
-
211
- /// Returns the result of applying `f` to each character in `ts`, concatenating the intermediate text values.
212
- ///
213
- /// ```motoko include=import
214
- /// // Replace all occurrences of '?' with "!!"
215
- /// let result = Text.translate("Motoko?", func(c) {
216
- /// if (c == '?') "!!"
217
- /// else Text.fromChar(c)
218
- /// }); // "Motoko!!"
219
- /// ```
220
- public func translate(t : Text, f : Char -> Text) : Text {
221
- var r = "";
222
- for (c in t.chars()) {
223
- r #= f(c)
224
- };
225
- return r
226
- };
227
-
228
- /// A pattern `p` describes a sequence of characters. A pattern has one of the following forms:
229
- ///
230
- /// * `#char c` matches the single character sequence, `c`.
231
- /// * `#text t` matches multi-character text sequence `t`.
232
- /// * `#predicate p` matches any single character sequence `c` satisfying predicate `p(c)`.
233
- ///
234
- /// A _match_ for `p` is any sequence of characters matching the pattern `p`.
235
- ///
236
- /// ```motoko include=import
237
- /// let charPattern = #char 'A';
238
- /// let textPattern = #text "phrase";
239
- /// let predicatePattern : Text.Pattern = #predicate (func(c) { c == 'A' or c == 'B' }); // matches "A" or "B"
240
- /// ```
241
- public type Pattern = {
242
- #char : Char;
243
- #text : Text;
244
- #predicate : (Char -> Bool)
245
- };
246
-
247
- private func take(n : Nat, cs : Iter.Iter<Char>) : Iter.Iter<Char> {
248
- var i = n;
249
- object {
250
- public func next() : ?Char {
251
- if (i == 0) return null;
252
- i -= 1;
253
- return cs.next()
254
- }
255
- }
256
- };
257
-
258
- private func empty() : Iter.Iter<Char> {
259
- object {
260
- public func next() : ?Char = null
261
- }
262
- };
263
-
264
- private type Match = {
265
- /// #success on complete match
266
- #success;
267
- /// #fail(cs,c) on partial match of cs, but failing match on c
268
- #fail : (cs : Iter.Iter<Char>, c : Char);
269
- /// #empty(cs) on partial match of cs and empty stream
270
- #empty : (cs : Iter.Iter<Char>)
271
- };
272
-
273
- private func sizeOfPattern(pat : Pattern) : Nat {
274
- switch pat {
275
- case (#text(t)) { t.size() };
276
- case (#predicate(_) or #char(_)) { 1 }
277
- }
278
- };
279
-
280
- private func matchOfPattern(pat : Pattern) : (cs : Iter.Iter<Char>) -> Match {
281
- switch pat {
282
- case (#char(p)) {
283
- func(cs : Iter.Iter<Char>) : Match {
284
- switch (cs.next()) {
285
- case (?c) {
286
- if (p == c) {
287
- #success
288
- } else {
289
- #fail(empty(), c)
290
- }
291
- };
292
- case null { #empty(empty()) }
293
- }
294
- }
295
- };
296
- case (#predicate(p)) {
297
- func(cs : Iter.Iter<Char>) : Match {
298
- switch (cs.next()) {
299
- case (?c) {
300
- if (p(c)) {
301
- #success
302
- } else {
303
- #fail(empty(), c)
304
- }
305
- };
306
- case null { #empty(empty()) }
307
- }
308
- }
309
- };
310
- case (#text(p)) {
311
- func(cs : Iter.Iter<Char>) : Match {
312
- var i = 0;
313
- let ds = p.chars();
314
- loop {
315
- switch (ds.next()) {
316
- case (?d) {
317
- switch (cs.next()) {
318
- case (?c) {
319
- if (c != d) {
320
- return #fail(take(i, p.chars()), c)
321
- };
322
- i += 1
323
- };
324
- case null {
325
- return #empty(take(i, p.chars()))
326
- }
327
- }
328
- };
329
- case null { return #success }
330
- }
331
- }
332
- }
333
- }
334
- }
335
- };
336
-
337
- private class CharBuffer(cs : Iter.Iter<Char>) : Iter.Iter<Char> = {
338
-
339
- var stack : Stack.Stack<(Iter.Iter<Char>, Char)> = Stack.Stack();
340
-
341
- public func pushBack(cs0 : Iter.Iter<Char>, c : Char) {
342
- stack.push((cs0, c))
343
- };
344
-
345
- public func next() : ?Char {
346
- switch (stack.peek()) {
347
- case (?(buff, c)) {
348
- switch (buff.next()) {
349
- case null {
350
- ignore stack.pop();
351
- return ?c
352
- };
353
- case oc {
354
- return oc
355
- }
356
- }
357
- };
358
- case null {
359
- return cs.next()
360
- }
361
- }
362
- }
363
- };
364
-
365
- /// Splits the input `Text` with the specified `Pattern`.
366
- ///
367
- /// Two fields are separated by exactly one match.
368
- ///
369
- /// ```motoko include=import
370
- /// let words = Text.split("This is a sentence.", #char ' ');
371
- /// Text.join("|", words) // "This|is|a|sentence."
372
- /// ```
373
- public func split(t : Text, p : Pattern) : Iter.Iter<Text> {
374
- let match = matchOfPattern(p);
375
- let cs = CharBuffer(t.chars());
376
- var state = 0;
377
- var field = "";
378
- object {
379
- public func next() : ?Text {
380
- switch state {
381
- case (0 or 1) {
382
- loop {
383
- switch (match(cs)) {
384
- case (#success) {
385
- let r = field;
386
- field := "";
387
- state := 1;
388
- return ?r
389
- };
390
- case (#empty(cs1)) {
391
- for (c in cs1) {
392
- field #= fromChar(c)
393
- };
394
- let r = if (state == 0 and field == "") {
395
- null
396
- } else {
397
- ?field
398
- };
399
- state := 2;
400
- return r
401
- };
402
- case (#fail(cs1, c)) {
403
- cs.pushBack(cs1, c);
404
- switch (cs.next()) {
405
- case (?ci) {
406
- field #= fromChar(ci)
407
- };
408
- case null {
409
- let r = if (state == 0 and field == "") {
410
- null
411
- } else {
412
- ?field
413
- };
414
- state := 2;
415
- return r
416
- }
417
- }
418
- }
419
- }
420
- }
421
- };
422
- case _ { return null }
423
- }
424
- }
425
- }
426
- };
427
-
428
- /// Returns a sequence of tokens from the input `Text` delimited by the specified `Pattern`, derived from start to end.
429
- /// A "token" is a non-empty maximal subsequence of `t` not containing a match for pattern `p`.
430
- /// Two tokens may be separated by one or more matches of `p`.
431
- ///
432
- /// ```motoko include=import
433
- /// let tokens = Text.tokens("this needs\n an example", #predicate (func(c) { c == ' ' or c == '\n' }));
434
- /// Text.join("|", tokens) // "this|needs|an|example"
435
- /// ```
436
- public func tokens(t : Text, p : Pattern) : Iter.Iter<Text> {
437
- let fs = split(t, p);
438
- object {
439
- public func next() : ?Text {
440
- switch (fs.next()) {
441
- case (?"") { next() };
442
- case ot { ot }
443
- }
444
- }
445
- }
446
- };
447
-
448
- /// Returns `true` if the input `Text` contains a match for the specified `Pattern`.
449
- ///
450
- /// ```motoko include=import
451
- /// Text.contains("Motoko", #text "oto") // true
452
- /// ```
453
- public func contains(t : Text, p : Pattern) : Bool {
454
- let match = matchOfPattern(p);
455
- let cs = CharBuffer(t.chars());
456
- loop {
457
- switch (match(cs)) {
458
- case (#success) {
459
- return true
460
- };
461
- case (#empty(cs1)) {
462
- return false
463
- };
464
- case (#fail(cs1, c)) {
465
- cs.pushBack(cs1, c);
466
- switch (cs.next()) {
467
- case null {
468
- return false
469
- };
470
- case _ {}; // continue
471
- }
472
- }
473
- }
474
- }
475
- };
476
-
477
- /// Returns `true` if the input `Text` starts with a prefix matching the specified `Pattern`.
478
- ///
479
- /// ```motoko include=import
480
- /// Text.startsWith("Motoko", #text "Mo") // true
481
- /// ```
482
- public func startsWith(t : Text, p : Pattern) : Bool {
483
- var cs = t.chars();
484
- let match = matchOfPattern(p);
485
- switch (match(cs)) {
486
- case (#success) { true };
487
- case _ { false }
488
- }
489
- };
490
-
491
- /// Returns `true` if the input `Text` ends with a suffix matching the specified `Pattern`.
492
- ///
493
- /// ```motoko include=import
494
- /// Text.endsWith("Motoko", #char 'o') // true
495
- /// ```
496
- public func endsWith(t : Text, p : Pattern) : Bool {
497
- let s2 = sizeOfPattern(p);
498
- if (s2 == 0) return true;
499
- let s1 = t.size();
500
- if (s2 > s1) return false;
501
- let match = matchOfPattern(p);
502
- var cs1 = t.chars();
503
- var diff : Nat = s1 - s2;
504
- while (diff > 0) {
505
- ignore cs1.next();
506
- diff -= 1
507
- };
508
- switch (match(cs1)) {
509
- case (#success) { true };
510
- case _ { false }
511
- }
512
- };
513
-
514
- /// Returns the input text `t` with all matches of pattern `p` replaced by text `r`.
515
- ///
516
- /// ```motoko include=import
517
- /// let result = Text.replace("abcabc", #char 'a', "A"); // "AbcAbc"
518
- /// ```
519
- public func replace(t : Text, p : Pattern, r : Text) : Text {
520
- let match = matchOfPattern(p);
521
- let size = sizeOfPattern(p);
522
- let cs = CharBuffer(t.chars());
523
- var res = "";
524
- label l loop {
525
- switch (match(cs)) {
526
- case (#success) {
527
- res #= r;
528
- if (size > 0) {
529
- continue l
530
- }
531
- };
532
- case (#empty(cs1)) {
533
- for (c1 in cs1) {
534
- res #= fromChar(c1)
535
- };
536
- break l
537
- };
538
- case (#fail(cs1, c)) {
539
- cs.pushBack(cs1, c)
540
- }
541
- };
542
- switch (cs.next()) {
543
- case null {
544
- break l
545
- };
546
- case (?c1) {
547
- res #= fromChar(c1)
548
- }; // continue
549
- }
550
- };
551
- return res
552
- };
553
-
554
- /// Strips one occurrence of the given `Pattern` from the beginning of the input `Text`.
555
- /// If you want to remove multiple instances of the pattern, use `Text.trimStart()` instead.
556
- ///
557
- /// ```motoko include=import
558
- /// // Try to strip a nonexistent character
559
- /// let none = Text.stripStart("abc", #char '-'); // null
560
- /// // Strip just one '-'
561
- /// let one = Text.stripStart("--abc", #char '-'); // ?"-abc"
562
- /// ```
563
- public func stripStart(t : Text, p : Pattern) : ?Text {
564
- let s = sizeOfPattern(p);
565
- if (s == 0) return ?t;
566
- var cs = t.chars();
567
- let match = matchOfPattern(p);
568
- switch (match(cs)) {
569
- case (#success) return ?fromIter(cs);
570
- case _ return null
571
- }
572
- };
573
-
574
- /// Strips one occurrence of the given `Pattern` from the end of the input `Text`.
575
- /// If you want to remove multiple instances of the pattern, use `Text.trimEnd()` instead.
576
- ///
577
- /// ```motoko include=import
578
- /// // Try to strip a nonexistent character
579
- /// let none = Text.stripEnd("xyz", #char '-'); // null
580
- /// // Strip just one '-'
581
- /// let one = Text.stripEnd("xyz--", #char '-'); // ?"xyz-"
582
- /// ```
583
- public func stripEnd(t : Text, p : Pattern) : ?Text {
584
- let s2 = sizeOfPattern(p);
585
- if (s2 == 0) return ?t;
586
- let s1 = t.size();
587
- if (s2 > s1) return null;
588
- let match = matchOfPattern(p);
589
- var cs1 = t.chars();
590
- var diff : Nat = s1 - s2;
591
- while (diff > 0) {
592
- ignore cs1.next();
593
- diff -= 1
594
- };
595
- switch (match(cs1)) {
596
- case (#success) return ?extract(t, 0, s1 - s2);
597
- case _ return null
598
- }
599
- };
600
-
601
- /// Trims the given `Pattern` from the start of the input `Text`.
602
- /// If you only want to remove a single instance of the pattern, use `Text.stripStart()` instead.
603
- ///
604
- /// ```motoko include=import
605
- /// let trimmed = Text.trimStart("---abc", #char '-'); // "abc"
606
- /// ```
607
- public func trimStart(t : Text, p : Pattern) : Text {
608
- let cs = t.chars();
609
- let size = sizeOfPattern(p);
610
- if (size == 0) return t;
611
- var matchSize = 0;
612
- let match = matchOfPattern(p);
613
- loop {
614
- switch (match(cs)) {
615
- case (#success) {
616
- matchSize += size
617
- }; // continue
618
- case (#empty(cs1)) {
619
- return if (matchSize == 0) {
620
- t
621
- } else {
622
- fromIter(cs1)
623
- }
624
- };
625
- case (#fail(cs1, c)) {
626
- return if (matchSize == 0) {
627
- t
628
- } else {
629
- fromIter(cs1) # fromChar(c) # fromIter(cs)
630
- }
631
- }
632
- }
633
- }
634
- };
635
-
636
- /// Trims the given `Pattern` from the end of the input `Text`.
637
- /// If you only want to remove a single instance of the pattern, use `Text.stripEnd()` instead.
638
- ///
639
- /// ```motoko include=import
640
- /// let trimmed = Text.trimEnd("xyz---", #char '-'); // "xyz"
641
- /// ```
642
- public func trimEnd(t : Text, p : Pattern) : Text {
643
- let cs = CharBuffer(t.chars());
644
- let size = sizeOfPattern(p);
645
- if (size == 0) return t;
646
- let match = matchOfPattern(p);
647
- var matchSize = 0;
648
- label l loop {
649
- switch (match(cs)) {
650
- case (#success) {
651
- matchSize += size
652
- }; // continue
653
- case (#empty(cs1)) {
654
- switch (cs1.next()) {
655
- case null break l;
656
- case (?_) return t
657
- }
658
- };
659
- case (#fail(cs1, c)) {
660
- matchSize := 0;
661
- cs.pushBack(cs1, c);
662
- ignore cs.next()
663
- }
664
- }
665
- };
666
- extract(t, 0, t.size() - matchSize)
667
- };
668
-
669
- /// Trims the given `Pattern` from both the start and end of the input `Text`.
670
- ///
671
- /// ```motoko include=import
672
- /// let trimmed = Text.trim("---abcxyz---", #char '-'); // "abcxyz"
673
- /// ```
674
- public func trim(t : Text, p : Pattern) : Text {
675
- let cs = t.chars();
676
- let size = sizeOfPattern(p);
677
- if (size == 0) return t;
678
- var matchSize = 0;
679
- let match = matchOfPattern(p);
680
- loop {
681
- switch (match(cs)) {
682
- case (#success) {
683
- matchSize += size
684
- }; // continue
685
- case (#empty(cs1)) {
686
- return if (matchSize == 0) { t } else { fromIter(cs1) }
687
- };
688
- case (#fail(cs1, c)) {
689
- let start = matchSize;
690
- let cs2 = CharBuffer(cs);
691
- cs2.pushBack(cs1, c);
692
- ignore cs2.next();
693
- matchSize := 0;
694
- label l loop {
695
- switch (match(cs2)) {
696
- case (#success) {
697
- matchSize += size
698
- }; // continue
699
- case (#empty(cs3)) {
700
- switch (cs1.next()) {
701
- case null break l;
702
- case (?_) return t
703
- }
704
- };
705
- case (#fail(cs3, c1)) {
706
- matchSize := 0;
707
- cs2.pushBack(cs3, c1);
708
- ignore cs2.next()
709
- }
710
- }
711
- };
712
- return extract(t, start, t.size() - matchSize - start)
713
- }
714
- }
715
- }
716
- };
717
-
718
- /// Compares `t1` and `t2` using the provided character-wise comparison function.
719
- ///
720
- /// ```motoko include=import
721
- /// import Char "mo:base/Char";
722
- ///
723
- /// Text.compareWith("abc", "ABC", func(c1, c2) { Char.compare(c1, c2) }) // #greater
724
- /// ```
725
- public func compareWith(
726
- t1 : Text,
727
- t2 : Text,
728
- cmp : (Char, Char) -> { #less; #equal; #greater }
729
- ) : { #less; #equal; #greater } {
730
- let cs1 = t1.chars();
731
- let cs2 = t2.chars();
732
- loop {
733
- switch (cs1.next(), cs2.next()) {
734
- case (null, null) { return #equal };
735
- case (null, ?_) { return #less };
736
- case (?_, null) { return #greater };
737
- case (?c1, ?c2) {
738
- switch (cmp(c1, c2)) {
739
- case (#equal) {}; // continue
740
- case other { return other }
741
- }
742
- }
743
- }
744
- }
745
- };
746
-
747
- /// Returns a UTF-8 encoded `Blob` from the given `Text`.
748
- ///
749
- /// ```motoko include=import
750
- /// let blob = Text.encodeUtf8("Hello");
751
- /// ```
752
- public let encodeUtf8 : Text -> Blob = Prim.encodeUtf8;
753
-
754
- /// Tries to decode the given `Blob` as UTF-8.
755
- /// Returns `null` if the blob is not valid UTF-8.
756
- ///
757
- /// ```motoko include=import
758
- /// let text = Text.decodeUtf8("\48\65\6C\6C\6F"); // ?"Hello"
759
- /// ```
760
- public let decodeUtf8 : Blob -> ?Text = Prim.decodeUtf8
761
- }