///|
/// line_framer returns a new Framer.
/// The messages are sent with a terminating cr+newline, and rely on json decode consistency
/// to determine message boundaries.
pub fn line_framer() -> &Framer {
  LineFramer::{  }
}

///|
pub struct LineFramer {}

///|
pub struct LineReader {
  in_ : &@io.ByteReader
}

///|
pub struct LineWriter {
  out : &@io.Writer
}

///|
pub impl Framer for LineFramer with fn reader(_self, in_) -> &Reader {
  LineReader::{ in_, }
}

///|
pub impl Framer for LineFramer with fn writer(_self, out) -> &Writer {
  LineWriter::{ out, }
}

///|
pub impl Reader for LineReader with fn read(self) -> (
  Message?,
  Int64,
  @io.IOError?,
) {
  let buf = @io.Buffer::new()
  let (n, err) = @io.copy_until(buf, self.in_, b'\n')
  guard err is None else { return (None, 0, err) }
  // Are these conversions really necessary?
  let msg : Message = @json.from_json(
    @json.parse(buf.to_string().trim().to_owned()),
  ) catch {
    e => return (None, 0, Some(@io.IOError(e.to_string())))
  }
  (Some(msg), n, None)
}

///|
pub impl Writer for LineWriter with fn write(self, msg) -> (Int64, @io.IOError?) {
  let s = msg.to_json().stringify()
  let body = @io.Buffer::new()
  let (_, err) = body.write_string("\{s}\r\n")
  guard err is None else { return (0, err) }
  let (n, err) = self.out.write(body.to_slice())
  guard err is None else { return (n.to_int64(), err) }
  (n.to_int64(), err)
}