Skip to content

Commit 5c29d76

Browse files
author
Devin Torres
committed
Add String.Unicode.{lstrip,rstrip}
1 parent 9b3d851 commit 5c29d76

File tree

3 files changed

+45
-40
lines changed

3 files changed

+45
-40
lines changed

lib/elixir/lib/string.ex

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ defmodule String do
1818
@type codepoint :: t
1919
@type grapheme :: t
2020

21-
# Entries considered as whitespace
22-
@whitespace [?\t, ?\n, ?\v, ?\f, ?\r, ?\s]
23-
2421
@doc """
2522
Checks if a string is printable considering it is encoded
2623
as UTF-8. Returns true if so, false otherwise.
@@ -186,28 +183,7 @@ defmodule String do
186183
187184
"""
188185
@spec rstrip(t) :: t
189-
190-
def rstrip(""), do: ""
191-
192-
def rstrip(string) do
193-
if :binary.last(string) in @whitespace do
194-
do_rstrip(string, "")
195-
else
196-
string
197-
end
198-
end
199-
200-
defp do_rstrip(<<char, string :: binary>>, buffer) when char in @whitespace do
201-
do_rstrip(string, <<char, buffer :: binary>>)
202-
end
203-
204-
defp do_rstrip(<<char, string :: binary>>, buffer) do
205-
<<buffer :: binary, char, do_rstrip(string, "") :: binary>>
206-
end
207-
208-
defp do_rstrip(<<>>, _) do
209-
<<>>
210-
end
186+
defdelegate rstrip(binary), to: String.Unicode
211187

212188
@doc """
213189
Returns a string where trailing `char` have been removed.
@@ -253,15 +229,7 @@ defmodule String do
253229
String.lstrip(" abc ") #=> "abc "
254230
255231
"""
256-
@spec lstrip(t) :: t
257-
258-
def lstrip(<<char, rest :: binary>>) when char in @whitespace do
259-
lstrip(rest)
260-
end
261-
262-
def lstrip(other) do
263-
other
264-
end
232+
defdelegate lstrip(binary), to: String.Unicode
265233

266234
@doc """
267235
Returns a string where leading `char` have been removed.

lib/elixir/priv/unicode.ex

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,20 @@ defmodule String.Unicode do
1212

1313
data_path = File.expand_path("../UnicodeData.txt", __FILE__)
1414

15-
codes = Enum.reduce File.iterator!(data_path), [], fn(line, acc) ->
15+
{ codes, whitespace } = Enum.reduce File.iterator!(data_path), { [], [] }, fn(line, { cacc, wacc }) ->
1616
[ codepoint, _name, _category,
17-
_class, _bidi, _decomposition,
17+
_class, bidi, _decomposition,
1818
_numeric_1, _numeric_2, _numeric_3,
1919
_bidi_mirror, _unicode_1, _iso,
2020
upper, lower, _title ] = :binary.split(line, ";", [:global])
2121

22-
if upper != "" or lower != "" do
23-
[{ to_binary.(codepoint), upper, lower }|acc]
24-
else
25-
acc
22+
cond do
23+
upper != "" or lower != "" ->
24+
{ [{ to_binary.(codepoint), upper, lower } | cacc], wacc }
25+
bidi in ["B", "S", "WS"] ->
26+
{ cacc, [to_binary.(codepoint) | wacc] }
27+
true ->
28+
{ cacc, wacc }
2629
end
2730
end
2831

@@ -70,6 +73,36 @@ defmodule String.Unicode do
7073
<< >>
7174
end
7275

76+
# Strip
77+
78+
def lstrip(""), do: ""
79+
80+
lc char inlist whitespace do
81+
args = quote do: [unquote(char) <> rest]
82+
exprs = quote do: lstrip(rest)
83+
def :lstrip, args, [], do: exprs
84+
end
85+
86+
def lstrip(other), do: other
87+
88+
def rstrip(""), do: ""
89+
90+
def rstrip(string) do
91+
do_rstrip(string, "")
92+
end
93+
94+
lc char inlist whitespace do
95+
args = quote do: [unquote(char) <> rest, buffer]
96+
exprs = quote do: do_rstrip(rest, unquote(char) <> buffer)
97+
defp :do_rstrip, args, [], do: exprs
98+
end
99+
100+
defp do_rstrip(<< char, string :: binary >>, buffer) do
101+
<< buffer :: binary, char, do_rstrip(string, "") :: binary >>
102+
end
103+
104+
defp do_rstrip(<<>>, _), do: <<>>
105+
73106
# Graphemes
74107

75108
lc codepoints inlist seqs do

lib/elixir/test/elixir/string_test.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ defmodule StringTest do
4747
assert String.rstrip(" abc a") == " abc a"
4848
assert String.rstrip("a abc a\n\n") == "a abc a"
4949
assert String.rstrip("a abc a\t\n\v\f\r\s") == "a abc a"
50+
assert String.rstrip("a abc a " <> <<31>>) == "a abc a"
51+
assert String.rstrip("a abc a" <> <<194,133>>) == "a abc a"
5052
assert String.rstrip(" abc aa", ?a) == " abc "
5153
assert String.rstrip(" abc __", ?_) == " abc "
5254
end
@@ -57,6 +59,8 @@ defmodule StringTest do
5759
assert String.lstrip("a abc a") == "a abc a"
5860
assert String.lstrip("\n\na abc a") == "a abc a"
5961
assert String.lstrip("\t\n\v\f\r\sa abc a") == "a abc a"
62+
assert String.lstrip(<<31>> <> " a abc a") == "a abc a"
63+
assert String.lstrip(<<194,133>> <> "a abc a") == "a abc a"
6064
assert String.lstrip("__ abc _", ?_) == " abc _"
6165
end
6266

0 commit comments

Comments
 (0)