Skip to content

Commit dd5a955

Browse files
authored
JavaScript: fix string_builder.reverse, cleanup (#300)
1 parent eeceba2 commit dd5a955

File tree

6 files changed

+65
-28
lines changed

6 files changed

+65
-28
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
- The `float` module gains the `divide` function.
66
- The `int` module gains the `divide`, `power`, and `square_root` functions.
77
- The `string` module gains the `first`, `last`, `capitalise` and `inspect` functions.
8-
- The `string` module gains the `first`, `last`, and `capitalise` functions.
8+
- Fixed a bug where `string_builder.reverse` would break utf8 strings on target JavaScript.
99
- Fixed a bug where `string.reverse` would break utf8 strings on target JavaScript.
1010
- Fixed a bug where `string.slice` would break utf8 strings on target JavaScript.
11+
- The `string_builder` module loses the `from_float` function. Use `float.to_string` instead.
1112
- Fixed the `int.power` and `float.power` functions by properly handling error cases.
1213
- The grapheme iterator used by `string.graphemes` is now locale independent on target JavaScript.
1314

src/gleam/float.gleam

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import gleam/order.{Order}
2-
import gleam/string_builder
32

43
/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was not
54
/// possible.
@@ -36,9 +35,17 @@ if javascript {
3635
/// ```
3736
///
3837
pub fn to_string(x: Float) -> String {
39-
x
40-
|> string_builder.from_float
41-
|> string_builder.to_string
38+
do_to_string(x)
39+
}
40+
41+
if erlang {
42+
external fn do_to_string(Float) -> String =
43+
"gleam_stdlib" "float_to_string"
44+
}
45+
46+
if javascript {
47+
external fn do_to_string(Float) -> String =
48+
"../gleam_stdlib.mjs" "float_to_string"
4249
}
4350

4451
/// Restricts a `Float` between a lower and upper bound.

src/gleam/string_builder.gleam

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
///
1515
pub external type StringBuilder
1616

17-
/// Create an empty `StringBuilder`. Useful as the start of a pipe chaning many
17+
/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many
1818
/// builders together.
1919
///
2020
pub fn new() -> StringBuilder {
@@ -161,22 +161,6 @@ if javascript {
161161
"../gleam_stdlib.mjs" "length"
162162
}
163163

164-
/// Creates a builder containing the textual representation of a given float.
165-
///
166-
pub fn from_float(f: Float) -> StringBuilder {
167-
do_from_float(f)
168-
}
169-
170-
if erlang {
171-
external fn do_from_float(Float) -> StringBuilder =
172-
"io_lib_format" "fwrite_g"
173-
}
174-
175-
if javascript {
176-
external fn do_from_float(Float) -> StringBuilder =
177-
"../gleam_stdlib.mjs" "float_to_string"
178-
}
179-
180164
/// Converts a builder to a new builder where the contents have been
181165
/// lowercased.
182166
///
@@ -223,8 +207,18 @@ if erlang {
223207
}
224208

225209
if javascript {
226-
external fn do_reverse(StringBuilder) -> StringBuilder =
227-
"../gleam_stdlib.mjs" "string_reverse"
210+
import gleam/list
211+
212+
fn do_reverse(builder: StringBuilder) -> StringBuilder {
213+
builder
214+
|> to_string
215+
|> do_to_graphemes
216+
|> list.reverse
217+
|> from_strings
218+
}
219+
220+
external fn do_to_graphemes(string: String) -> List(String) =
221+
"../gleam_stdlib.mjs" "graphemes"
228222
}
229223

230224
/// Splits a builder on a given pattern into a list of builders.
@@ -303,7 +297,6 @@ if javascript {
303297
/// True
304298
/// ```
305299
///
306-
///
307300
pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool {
308301
do_is_equal(a, b)
309302
}
@@ -333,7 +326,6 @@ if javascript {
333326
/// True
334327
/// ```
335328
///
336-
///
337329
pub fn is_empty(builder: StringBuilder) -> Bool {
338330
do_is_empty(builder)
339331
}

src/gleam_stdlib.erl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
percent_encode/1, percent_decode/1, regex_check/2, regex_split/2,
1111
base_decode64/1, parse_query/1, bit_string_concat/1, size_of_tuple/1,
1212
decode_tuple/1, tuple_get/2, classify_dynamic/1, print/1, println/1,
13-
inspect/1]).
13+
inspect/1, float_to_string/1]).
1414

1515
%% Taken from OTP's uri_string module
1616
-define(DEC2HEX(X),
@@ -374,4 +374,7 @@ inspect(Any) when is_function(Any) ->
374374
),
375375
["//fn(", Args, ") { ... }"];
376376
inspect(Any) ->
377-
["//erl(", io_lib:format("~p", [Any]), ")"].
377+
["//erl(", io_lib:format("~p", [Any]), ")"].
378+
379+
float_to_string(Float) when is_float(Float) ->
380+
erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)).

src/gleam_stdlib.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ export function string_length(string) {
9393
}
9494
}
9595

96+
export function graphemes(string) {
97+
return List.fromArray(
98+
Array.from(graphemes_iterator(string)).map(((item) => item.segment ))
99+
);
100+
}
101+
96102
function graphemes_iterator(string) {
97103
if (Intl && Intl.Segmenter) {
98104
return new Intl.Segmenter().segment(string)[Symbol.iterator]();

test/gleam/string_builder_test.gleam

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,34 @@ pub fn string_builder_test() {
3434
|> should.equal(13)
3535
}
3636

37+
pub fn reverse_test() {
38+
"Ĺo͂řȩm̅"
39+
|> string_builder.from_string
40+
|> string_builder.reverse
41+
|> string_builder.reverse
42+
|> string_builder.to_string
43+
|> should.equal("Ĺo͂řȩm̅")
44+
45+
"Ĺo͂řȩm̅"
46+
|> string_builder.from_string
47+
|> string_builder.reverse
48+
|> string_builder.to_string
49+
|> should.equal("m̅ȩřo͂Ĺ")
50+
51+
"👶🏿"
52+
|> string_builder.from_string
53+
|> string_builder.reverse
54+
|> string_builder.reverse
55+
|> string_builder.to_string
56+
|> should.equal("👶🏿")
57+
58+
"👶🏿"
59+
|> string_builder.from_string
60+
|> string_builder.reverse
61+
|> string_builder.to_string
62+
|> should.equal("👶🏿")
63+
}
64+
3765
pub fn lowercase_test() {
3866
["Gleam", "Gleam"]
3967
|> string_builder.from_strings

0 commit comments

Comments
 (0)