38 lines
1.4 KiB
FSharp
38 lines
1.4 KiB
FSharp
namespace rprint
|
|
|
|
module Rprint =
|
|
let printer = new System.Threading.AsyncLocal<string -> unit>()
|
|
let _ =
|
|
printer.Value <- System.Console.Write
|
|
|
|
let rprint format =
|
|
// This is a new friend of mine. kprintf takes a format string and a continuation.
|
|
// it returns a function that takes enough values to satisfy the format string.
|
|
// in the end it produces a string that is passed to the continuation.
|
|
Printf.kprintf (fun s -> printer.Value s) format
|
|
|
|
let rprintn format =
|
|
Printf.kprintf (fun s -> printer.Value (s + System.Environment.NewLine)) format
|
|
|
|
// Takes a thunk. All output printed through rprint gets redirected to a stringBuilder
|
|
// for all calls to rprint within the extent of withOutputToString
|
|
let withOutputToString f =
|
|
let sb = System.Text.StringBuilder()
|
|
let original = printer.Value
|
|
|
|
// Bind om till StringBuilder
|
|
printer.Value <- fun s -> sb.Append s |> ignore
|
|
try
|
|
f ()
|
|
sb.ToString().TrimEnd()
|
|
finally
|
|
printer.Value <- original
|
|
|
|
let withOutputToStringBuilder (builder: System.Text.StringBuilder) f =
|
|
let original = printer.Value
|
|
|
|
printer.Value <- (fun s -> builder.Append(s) |> ignore)
|
|
try
|
|
f ()
|
|
finally
|
|
printer.Value <- original
|