Skip to content

Commit b78c3bc

Browse files
author
José Valim
committed
Add Stream.resource/3
1 parent 94be8a1 commit b78c3bc

File tree

5 files changed

+202
-177
lines changed

5 files changed

+202
-177
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* [Kernel] Add `Enum.reverse/2`
77
* [Kernel] Implement `defmodule/2`, `@/1`, `def/2` and friends in Elixir itself. `case/2`, `try/2` and `receive/1` have been made special forms. `var!/1`, `var!/2` and `alias!/1` have also been implemented in Elixir and demoted from special forms
88
* [Record] Support dynamic fields in `defrecordp`
9+
* [Stream] Add `Stream.resource/3`
910
* [Typespec] Support `is_var/1` in typespecs
1011

1112
* Bug fixes

lib/elixir/lib/file.ex

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -970,36 +970,31 @@ defmodule File do
970970
modes = open_defaults(modes, true)
971971
bin = nil? List.keyfind(modes, :encoding, 0)
972972

973-
fn(acc, fun) ->
974-
case F.open(path, modes) do
975-
{ :ok, device } -> device
976-
{ :error, reason } ->
977-
raise File.Error, reason: reason, action: "stream", path: to_string(path)
973+
start_fun =
974+
fn ->
975+
case F.open(path, modes) do
976+
{ :ok, device } -> device
977+
{ :error, reason } ->
978+
raise File.Error, reason: reason, action: "stream", path: to_string(path)
979+
end
978980
end
979981

980-
try do
981-
case bin do
982-
true -> IO.binstream(device, line_or_bytes, acc, fun)
983-
false -> IO.stream(device, line_or_bytes, acc, fun)
984-
end
985-
after
986-
F.close(device)
982+
next_fun =
983+
case bin do
984+
true -> &IO.do_binstream(&1, line_or_bytes)
985+
false -> &IO.do_stream(&1, line_or_bytes)
987986
end
988-
end
987+
988+
Stream.resource(start_fun, next_fun, &F.close/1)
989989
end
990990

991991
@doc false
992992
def binstream!(file, mode // [], line_or_bytes // :line) do
993993
IO.write "File.binstream! is deprecated, simply use File.stream! instead\n" <>
994994
Exception.format_stacktrace
995-
fn(fun, acc) ->
996-
device = open!(file, mode)
997-
try do
998-
IO.binstream(device, line_or_bytes, fun, acc)
999-
after
1000-
F.close(device)
1001-
end
1002-
end
995+
Stream.resource(fn -> open!(file, mode) end,
996+
&IO.do_binstream(&1, line_or_bytes),
997+
&F.close/1)
1003998
end
1004999

10051000
@doc """

lib/elixir/lib/io.ex

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ defmodule IO do
244244
"""
245245
@spec stream(device, :line | pos_integer) :: Enumerable.t
246246
def stream(device, line_or_codepoints) do
247-
fn(acc, f) -> stream(map_dev(device), line_or_codepoints, acc, f) end
247+
Stream.unfold(map_dev(device), &do_stream(&1, line_or_codepoints))
248248
end
249249

250250
@doc """
@@ -257,30 +257,30 @@ defmodule IO do
257257
"""
258258
@spec binstream(device, :line | pos_integer) :: Enumerable.t
259259
def binstream(device, line_or_bytes) do
260-
fn(acc, f) -> binstream(map_dev(device), line_or_bytes, acc, f) end
260+
Stream.unfold(map_dev(device), &do_binstream(&1, line_or_bytes))
261261
end
262262

263263
@doc false
264-
def stream(device, what, acc, fun) do
264+
def do_stream(device, what) do
265265
case read(device, what) do
266266
:eof ->
267-
acc
267+
nil
268268
{ :error, reason } ->
269269
raise IO.StreamError, reason: reason
270270
data ->
271-
stream(device, what, fun.(data, acc), fun)
271+
{ data, device }
272272
end
273273
end
274274

275275
@doc false
276-
def binstream(device, what, acc, fun) do
276+
def do_binstream(device, what) do
277277
case binread(device, what) do
278278
:eof ->
279-
acc
279+
nil
280280
{ :error, reason } ->
281281
raise IO.StreamError, reason: reason
282282
data ->
283-
binstream(device, what, fun.(data, acc), fun)
283+
{ data, device }
284284
end
285285
end
286286

0 commit comments

Comments
 (0)