/* * Copyright 2025 Ry Wiese * * Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE.md file. */////// Trait for types that can be written to, and its functions.///pubmod Writable {use IoError.ErrorKinduse IoError.IoErrorimport java.io.IOExceptionimport java.io.OutputStreamimport java.lang.System////// Trait for types that can be written to.///pubtraitWritable[t] {////// Type of each element that can be written to the resource.///typeElm: Type////// Effect associated with writing to the underlying resource.///typeAef: Eff////// Reads `k` items from `b` and writes them into the underlying resource.////// Returns `Ok(k)` to signify that `k` items were successfully read and written to `r`.////// Guarantees that `0 <= k <= length(b)`.////// Returns `Err(e)` if some underlying I/O error occurs.///pubdefwrite(buffer: Array[Writable.Elm[t], r], writer: t): Result[IoError, Int32] \ r + Writable.Aef[t] }instanceWritable[OutputStream] {typeElm = Int8typeAef = IOpubdefwrite(b: Array[Int8, r], r: OutputStream): Result[IoError, Int32] \ r + IO =try {r.write(b);checked_ecast(Ok(Array.length(b))) } catch {caseex: IOException => Err(IoError(ErrorKind.Other, ex.getMessage())) } }////// Writes `string` to `writer`.///pubdefwriteString(string: String, writer: t): Result[IoError, Unit] \ Writable.Aef[t] withWritable[t] whereWritable.Elm[t] ~ Char =regionrc {letbuffer = String.toArray(rc, string);forM (charsWritten <- Writable.write(buffer, writer);_ <- if (charsWritten<String.length(string)) {writeString(string |> String.drop(charsWritten), writer) } else Ok(()) ) yield() }////// Writes a new line separator to `writer`.////// The new line separator is platform dependent, and is determined by the "line.separator" system property.///pubdefwriteNewLine(writer: t): Result[IoError, Unit] \ IO + Writable.Aef[t] withWritable[t] whereWritable.Elm[t] ~ Char =letnewLine = System.getProperty("line.separator");writeString(newLine, writer)////// Writes `line` to `writer` and appends a new line separator.////// The new line separator is platform dependent, and is determined by the "line.separator" system property.///pubdefwriteLine(line: String, writer: t): Result[IoError, Unit] \ IO + Writable.Aef[t] withWritable[t] whereWritable.Elm[t] ~ Char =forM (_ <- writeString(line, writer);_ <- writeNewLine(writer) ) yield()}