Skip to content

Commit

Permalink
Remove usages of std:io::Chars
Browse files Browse the repository at this point in the history
  • Loading branch information
gwenn committed May 1, 2018
1 parent 3a58e32 commit 4bd5f6b
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 20 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
@@ -1,7 +1,5 @@
sudo: false
language: rust
rust:
- nightly
script:
- cargo build --verbose
- cargo test --verbose
6 changes: 0 additions & 6 deletions README.md
Expand Up @@ -17,12 +17,6 @@ Readline implementation in Rust that is based on [Antirez' Linenoise](https://gi
* Powershell ISE is not supported, check [issue #56](https://github.com/kkawakam/rustyline/issues/56)
* Mintty (Cygwin/Mingw) is not supported

## Build
This project uses Cargo and Rust nightly
```bash
cargo build --release
```

## Example
```rust
extern crate rustyline;
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Expand Up @@ -2,7 +2,7 @@ environment:
TARGET: x86_64-pc-windows-msvc
install:
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- rustup-init -yv --default-toolchain nightly --default-host %TARGET%
- rustup-init -yv --default-toolchain stable --default-host %TARGET%
- set PATH=%PATH%;%USERPROFILE%\.cargo\bin
- rustc -V
- cargo -V
Expand Down
7 changes: 4 additions & 3 deletions src/error.rs
Expand Up @@ -6,6 +6,7 @@ use std::char;
use std::error;
use std::fmt;
use std::io;
use std::str;

/// The error type for Rustyline errors that can arise from
/// I/O related errors or Errno when using the nix-rust library
Expand All @@ -19,7 +20,7 @@ pub enum ReadlineError {
Interrupted,
/// Chars Error
#[cfg(unix)]
Char(io::CharsError),
Char(str::Utf8Error),
/// Unix Error from syscall
#[cfg(unix)]
Errno(nix::Error),
Expand Down Expand Up @@ -79,8 +80,8 @@ impl From<nix::Error> for ReadlineError {
}

#[cfg(unix)]
impl From<io::CharsError> for ReadlineError {
fn from(err: io::CharsError) -> ReadlineError {
impl From<str::Utf8Error> for ReadlineError {
fn from(err: str::Utf8Error) -> ReadlineError {
ReadlineError::Char(err)
}
}
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Expand Up @@ -15,7 +15,6 @@
//! Err(_) => println!("No input"),
//! }
//! ```
#![feature(io)]
#![allow(unknown_lints)]

extern crate libc;
Expand Down
48 changes: 41 additions & 7 deletions src/tty/unix.rs
@@ -1,6 +1,6 @@
//! Unix specific definitions
use std;
use std::io::{self, Chars, Read, Stdout, Write};
use std::io::{self, Read, Stdout, Write};
use std::sync;
use std::sync::atomic;

Expand Down Expand Up @@ -96,16 +96,17 @@ impl Read for StdinRaw {

/// Console input reader
pub struct PosixRawReader {
chars: Chars<StdinRaw>,
stdin: StdinRaw,
timeout_ms: i32,
buf: [u8; 4],
}

impl PosixRawReader {
fn new(config: &Config) -> Result<PosixRawReader> {
let stdin = StdinRaw {};
Ok(PosixRawReader {
chars: stdin.chars(),
stdin: StdinRaw{},
timeout_ms: config.keyseq_timeout(),
buf: [0; 4],
})
}

Expand Down Expand Up @@ -258,6 +259,26 @@ impl PosixRawReader {
}
}

// https://tools.ietf.org/html/rfc3629
static UTF8_CHAR_WIDTH: [u8; 256] = [
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
];

impl RawReader for PosixRawReader {
fn next_key(&mut self, single_esc_abort: bool) -> Result<KeyPress> {
let c = try!(self.next_char());
Expand Down Expand Up @@ -287,9 +308,22 @@ impl RawReader for PosixRawReader {
}

fn next_char(&mut self) -> Result<char> {
match self.chars.next() {
Some(c) => Ok(try!(c)),
None => Err(error::ReadlineError::Eof),
let n = try!(self.stdin.read(&mut self.buf[..1]));
if n == 0 {
return Err(error::ReadlineError::Eof);
}
let first = self.buf[0];
if first >= 128 {
let width = UTF8_CHAR_WIDTH[first as usize] as usize;
if width == 0 {
try!(std::str::from_utf8(&self.buf[..1]));
unreachable!()
}
try!(self.stdin.read_exact(&mut self.buf[1..width]));
let s = try!(std::str::from_utf8(&self.buf[..width]));
Ok(s.chars().next().unwrap())
} else {
return Ok(first as char);
}
}
}
Expand Down

0 comments on commit 4bd5f6b

Please sign in to comment.