fix ReadlineStream peek_char using CharReader

This commit is contained in:
Mark
2023-06-29 14:58:15 -06:00
parent a6a0cef9fc
commit bb09de1805
2 changed files with 33 additions and 24 deletions

View File

@@ -111,7 +111,7 @@ impl<R> CharReader<R> {
} }
impl<R: Read> CharReader<R> { impl<R: Read> CharReader<R> {
fn refresh_buffer(&mut self) -> io::Result<&[u8]> { pub fn refresh_buffer(&mut self) -> io::Result<&[u8]> {
// If we've reached the end of our internal buffer then we need to fetch // If we've reached the end of our internal buffer then we need to fetch
// some more data from the underlying reader. // some more data from the underlying reader.
// Branch using `>=` instead of the more correct `==` // Branch using `>=` instead of the more correct `==`

View File

@@ -83,7 +83,7 @@ fn get_prompt() -> &'static str {
#[derive(Debug)] #[derive(Debug)]
pub struct ReadlineStream { pub struct ReadlineStream {
rl: Editor<Helper>, rl: Editor<Helper>,
pending_input: Cursor<String>, pending_input: CharReader<Cursor<String>>,
add_history: bool, add_history: bool,
} }
@@ -107,7 +107,7 @@ impl ReadlineStream {
ReadlineStream { ReadlineStream {
rl, rl,
pending_input: Cursor::new(pending_input.to_owned()), pending_input: CharReader::new(Cursor::new(pending_input.to_owned())),
add_history: add_history, add_history: add_history,
} }
} }
@@ -119,29 +119,35 @@ impl ReadlineStream {
#[inline] #[inline]
pub fn reset(&mut self) { pub fn reset(&mut self) {
self.pending_input.get_mut().clear(); self.pending_input.reset_buffer();
self.pending_input.set_position(0);
let pending_input = self.pending_input.get_mut();
pending_input.get_mut().clear();
pending_input.set_position(0);
} }
fn call_readline(&mut self) -> std::io::Result<usize> { fn call_readline(&mut self) -> std::io::Result<usize> {
match self.rl.readline(get_prompt()) { match self.rl.readline(get_prompt()) {
Ok(text) => { Ok(text) => {
*self.pending_input.get_mut() = text; self.pending_input.reset_buffer();
self.pending_input.set_position(0);
*self.pending_input.get_mut().get_mut() = text;
self.pending_input.get_mut().set_position(0);
unsafe { unsafe {
if PROMPT { if PROMPT {
self.rl.history_mut().add(self.pending_input.get_ref()); self.rl.history_mut().add(self.pending_input.get_ref().get_ref());
self.save_history(); self.save_history();
PROMPT = false; PROMPT = false;
} }
} }
if self.pending_input.get_ref().chars().last() != Some('\n') { if self.pending_input.get_ref().get_ref().chars().last() != Some('\n') {
*self.pending_input.get_mut() += "\n"; *self.pending_input.get_mut().get_mut() += "\n";
} }
Ok(self.pending_input.get_ref().len()) Ok(self.pending_input.get_ref().get_ref().len())
} }
Err(ReadlineError::Eof) => Ok(0), Err(ReadlineError::Eof) => Ok(0),
Err(e) => Err(Error::new(ErrorKind::InvalidInput, e)), Err(e) => Err(Error::new(ErrorKind::InvalidInput, e)),
@@ -164,9 +170,13 @@ impl ReadlineStream {
} }
} }
#[inline]
pub(crate) fn peek_byte(&mut self) -> std::io::Result<u8> { pub(crate) fn peek_byte(&mut self) -> std::io::Result<u8> {
let bytes = self.pending_input.refresh_buffer()?;
let byte = bytes.iter().next().cloned();
loop { loop {
match self.pending_input.get_ref().bytes().next() { match byte {
Some(0) => { Some(0) => {
return Ok(0); return Ok(0);
} }
@@ -178,7 +188,7 @@ impl ReadlineStream {
return Err(e); return Err(e);
} }
Ok(0) => { Ok(0) => {
self.pending_input.get_mut().push('\u{0}'); self.pending_input.get_mut().get_mut().push('\u{0}');
return Ok(0); return Ok(0);
} }
_ => { _ => {
@@ -203,24 +213,23 @@ impl Read for ReadlineStream {
} }
impl CharRead for ReadlineStream { impl CharRead for ReadlineStream {
#[inline]
fn peek_char(&mut self) -> Option<std::io::Result<char>> { fn peek_char(&mut self) -> Option<std::io::Result<char>> {
loop { loop {
let pos = self.pending_input.position() as usize; match self.pending_input.peek_char() {
Some(Ok('\u{0}')) => {
match self.pending_input.get_ref()[pos ..].chars().next() {
Some('\u{0}') => {
return Some(Ok('\u{0}')); return Some(Ok('\u{0}'));
} }
Some(c) => { Some(Ok(c)) => {
return Some(Ok(c)); return Some(Ok(c));
} }
None => { _ => {
match self.call_readline() { match self.call_readline() {
Err(e) => { Err(e) => {
return Some(Err(e)); return Some(Err(e));
} }
Ok(0) => { Ok(0) => {
self.pending_input.get_mut().push('\u{0}'); self.pending_input.get_mut().get_mut().push('\u{0}');
return Some(Ok('\u{0}')); return Some(Ok('\u{0}'));
} }
_ => { _ => {
@@ -232,14 +241,14 @@ impl CharRead for ReadlineStream {
} }
} }
#[inline]
fn consume(&mut self, nread: usize) { fn consume(&mut self, nread: usize) {
let offset = self.pending_input.position() as usize; self.pending_input.consume(nread);
self.pending_input.set_position((offset + nread) as u64);
} }
#[inline]
fn put_back_char(&mut self, c: char) { fn put_back_char(&mut self, c: char) {
let offset = self.pending_input.position() as usize; self.pending_input.put_back_char(c);
self.pending_input.set_position((offset - c.len_utf8()) as u64);
} }
} }