/* * Copyright 2019 Stephen Tetley * * Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE.md file. */////// Type of mutable string builders, and its functions.///pubmod StringBuilder {use IoError.IoErrorimport java.lang.{StringBuilder => JStringBuilder}////// Type of mutable string builders.///pubenumStringBuilder[_: Region](JStringBuilder)instanceWritable[StringBuilder[r]] {typeElm = ChartypeAef = rpubdefwrite(buffer: Array[Char, r1], sb: StringBuilder[r]): Result[IoError, Int32] \ r1 + r =letlen = Array.length(buffer);Array.forEach(c -> StringBuilder.append(c, sb), buffer); Ok(len) }////// Returns a new mutable StringBuilder.///pubdefempty(_: Region[r]): StringBuilder[r] \ r = StringBuilder(unsafeIOasr { new JStringBuilder() })////// Append `x` to the StringBuilder `sb`.///pubdefappend(x: a, sb: StringBuilder[r]): Unit \ rwithToString[a] =lets = ToString.toString(x);s`appendString`sb;()////// Append the String `s` to the StringBuilder `sb`.///pubdefappendString(s: String, sb: StringBuilder[r]): Unit \ r =let StringBuilder(msb) = sb;discardunsafeIOasr { msb.append(s) }////// Append the code point `cp` to the StringBuilder `sb`.///pubdefappendCodePoint(cp: Int32, sb: StringBuilder[r]): Unit \ r =let StringBuilder(msb) = sb;discardunsafeIOasr { msb.appendCodePoint(cp) }////// Append the system line separator to the StringBuilder `sb`.///pubdefappendLineSeparator(sb: StringBuilder[r]): Unit \ r =String.lineSeparator()`appendString`sb////// Append the String `s` followed by the system line separator to the StringBuilder `sb`.///pubdefappendLine(s: String, sb: StringBuilder[r]): Unit \ r =s`appendString`sb;appendLineSeparator(sb)////// Appends `f(x)` to the string builder `sb`.///pubdefappendLineWith(f: a -> String \ ef, x: a, sb: StringBuilder[r]): Unit \ { ef, r } =f(x) `appendString`sb;appendLineSeparator(sb)////// Appends each string in the array `a` to the string builder `sb`.///pubdefappendLines(a: Array[String, r1], sb: StringBuilder[r2]): Unit \ { r1, r2 } =Array.forEach(x -> appendLine(x, sb), a)////// Appends `f(x)` for each x in the foldable collection `t` to the string builder `sb`.///pubdefappendLinesWith(f: a -> String \ ef, t: t[a], sb: StringBuilder[r]): Unit \ (ef + r + Foldable.Aef[t]) withFoldable[t] =Foldable.forEach(x -> appendLineWith(f, x, sb), t)////// Append the array of strings `a` separating each pair of string with `sep` to the StringBuilder `sb`.///pubdefintercalate(sep: String, a: Array[String, r1], sb: StringBuilder[r2]): Unit \ { r1, r2 } =letappend1 = (i, s) ->if (i>0) {appendString(sep, sb);appendString(s, sb) } else {appendString(s, sb) };Array.forEachWithIndex(append1, a)////// Returns an iterator over `sb`.///pubdefiterator(rc: Region[r1], sb: StringBuilder[r2]): Iterator[Char, r1 + r2, r1] \ { r1, r2 } =let StringBuilder(msb) = sb;Iterator.range(rc, 0, length(sb)) |> Iterator.map(i -> unsafeIOasr2 { msb.charAt(i) })////// Return the number of characters in the StringBuilder `sb`.///pubdeflength(sb: StringBuilder[r]): Int32 \ r =let StringBuilder(msb) = sb;unsafeIOasr { msb.length() }////// Return the number of characters in the StringBuilder `sb`.///pubdefsize(sb: StringBuilder[r]): Int32 \ r = length(sb)////// Sets the length of the StringBuilder `sb`.///pubdefsetLength(newLength: Int32, sb: StringBuilder[r]): Unit \ r =let StringBuilder.StringBuilder(msb) = sb;unsafeIOasr { msb.setLength(newLength) }////// Convert the StringBuilder `sb` to a string.///pubdeftoString(sb: StringBuilder[r]): String \ r =let StringBuilder(msb) = sb;unsafeIOasr { msb.toString() }}