use super::*;
use std::io;
impl Output<Write> {
pub fn into_read(self) -> Output<Read> {
let Output {
buf, lines_pos, tx, ..
} = self;
let state = Read {
buf: String::new(),
start: 0,
prompt_start: buf.len(),
prompt_end: buf.len(),
lines_idx: lines_pos.len(),
};
Output {
state,
buf,
lines_pos,
tx,
}
}
pub fn write_str(&mut self, contents: &str) {
self.push_str(contents);
}
pub fn write_line(&mut self, contents: &str) {
for ch in contents.chars() {
self.push_ch(ch);
}
self.push_ch('\n');
}
pub fn erase_last_line(&mut self) {
self.buf
.truncate(self.lines_pos.last().map(|x| x + 1).unwrap_or(0));
self.send_line_chg();
}
}
impl io::Write for Output<Write> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let s = String::from_utf8_lossy(buf);
self.push_str(&s);
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn erase_last_line() {
let mut o = Output::new().into_write();
o.write_str("Hello\nworld");
o.erase_last_line();
assert_eq!(o.buffer(), "Hello\n");
o.erase_last_line();
assert_eq!(o.buffer(), "Hello\n");
let mut o = Output::new().into_write();
o.write_str("Hello");
o.erase_last_line();
assert_eq!(o.buffer(), "");
}
#[test]
fn writing_line() {
let mut o = Output::new().into_write();
let rx = o.listen();
o.write_line("Hello, world!");
o.close();
let msgs = rx.iter().collect::<Vec<_>>();
assert_eq!(o.buffer(), "Hello, world!\n");
assert_eq!(
&msgs,
&[
OutputChange::CurrentLine("Hello, world!".to_owned()),
OutputChange::NewLine
]
);
}
}