1defmodule Alchemist.Helpers.CaptureIO do 2 3 def capture_io(fun) do 4 do_capture_io(:standard_io, [], fun) 5 end 6 7 defp do_capture_io(:standard_io, options, fun) do 8 prompt_config = Keyword.get(options, :capture_prompt, true) 9 input = Keyword.get(options, :input, "") 10 11 original_gl = Process.group_leader() 12 {:ok, capture_gl} = StringIO.open(input, capture_prompt: prompt_config) 13 try do 14 Process.group_leader(self(), capture_gl) 15 do_capture_io(capture_gl, fun) 16 after 17 Process.group_leader(self(), original_gl) 18 end 19 end 20 21 def do_capture_io(string_io, fun) do 22 try do 23 _ = fun.() 24 :ok 25 catch 26 kind, reason -> 27 stack = System.stacktrace() 28 _ = StringIO.close(string_io) 29 :erlang.raise(kind, reason, stack) 30 else 31 :ok -> 32 {:ok, output} = StringIO.close(string_io) 33 elem(output, 1) 34 end 35 end 36end 37