API Cleanup - part 1 (#235)

This commit is contained in:
Zrzka 2019-09-19 13:12:16 +02:00 committed by Timon
parent 7d47354307
commit 41de9a63a1
21 changed files with 169 additions and 139 deletions

View File

@ -29,12 +29,4 @@ script:
- if [ "$TRAVIS_RUST_VERSION" = "stable" ]; then cargo fmt --all -- --check; fi - if [ "$TRAVIS_RUST_VERSION" = "stable" ]; then cargo fmt --all -- --check; fi
- cargo build - cargo build
- if [ "$TRAVIS_OS_NAME" = "windows" ]; then cargo test --all -- --nocapture --test-threads 1; else cargo test --all --exclude crossterm_winapi -- --nocapture --test-threads 1; fi - if [ "$TRAVIS_OS_NAME" = "windows" ]; then cargo test --all -- --nocapture --test-threads 1; else cargo test --all --exclude crossterm_winapi -- --nocapture --test-threads 1; fi
- | - scripts/test-examples.sh
pushd examples/program_examples
for d in */ ; do
pushd "$d"
cargo build
if [ "$TRAVIS_RUST_VERSION" = "stable" ]; then cargo fmt --all -- --check; fi
popd
done
popd

View File

@ -29,9 +29,7 @@ trait ITerminalCursor: Sync + Send {
/// Goto location (`x`, `y`) in the current terminal window. /// Goto location (`x`, `y`) in the current terminal window.
fn goto(&self, x: u16, y: u16) -> Result<()>; fn goto(&self, x: u16, y: u16) -> Result<()>;
/// Get the cursor location `(x, y)` in the current terminal window. /// Get the cursor location `(x, y)` in the current terminal window.
/// fn pos(&self) -> Result<(u16, u16)>;
/// `(0, 0)` is returned in case of an error.
fn pos(&self) -> (u16, u16);
/// Move cursor `n` times up /// Move cursor `n` times up
fn move_up(&self, count: u16) -> Result<()>; fn move_up(&self, count: u16) -> Result<()>;
/// Move the cursor `n` times to the right. /// Move the cursor `n` times to the right.

View File

@ -51,7 +51,7 @@ impl ITerminalCursor for AnsiCursor {
Ok(()) Ok(())
} }
fn pos(&self) -> (u16, u16) { fn pos(&self) -> Result<(u16, u16)> {
get_cursor_position() get_cursor_position()
} }
@ -115,13 +115,17 @@ mod tests {
fn reset_safe_ansi() { fn reset_safe_ansi() {
if try_enable_ansi() { if try_enable_ansi() {
let cursor = AnsiCursor::new(); let cursor = AnsiCursor::new();
let (x, y) = cursor.pos(); let pos = cursor.pos();
assert!(pos.is_ok());
let (x, y) = pos.unwrap();
assert!(cursor.save_position().is_ok()); assert!(cursor.save_position().is_ok());
assert!(cursor.goto(5, 5).is_ok()); assert!(cursor.goto(5, 5).is_ok());
assert!(cursor.reset_position().is_ok()); assert!(cursor.reset_position().is_ok());
let (x_saved, y_saved) = cursor.pos(); let pos = cursor.pos();
assert!(pos.is_ok());
let (x_saved, y_saved) = pos.unwrap();
assert_eq!(x, x_saved); assert_eq!(x, x_saved);
assert_eq!(y, y_saved); assert_eq!(y, y_saved);
@ -134,10 +138,14 @@ mod tests {
fn goto_ansi() { fn goto_ansi() {
if try_enable_ansi() { if try_enable_ansi() {
let cursor = AnsiCursor::new(); let cursor = AnsiCursor::new();
let (x_saved, y_saved) = cursor.pos(); let pos = cursor.pos();
assert!(pos.is_ok());
let (x_saved, y_saved) = pos.unwrap();
assert!(cursor.goto(5, 5).is_ok()); assert!(cursor.goto(5, 5).is_ok());
let (x, y) = cursor.pos(); let pos = cursor.pos();
assert!(pos.is_ok());
let (x, y) = pos.unwrap();
assert!(cursor.goto(x_saved, y_saved).is_ok()); assert!(cursor.goto(x_saved, y_saved).is_ok());

View File

@ -59,32 +59,32 @@ impl TerminalCursor {
/// ///
/// # Remarks /// # Remarks
/// position is 0-based, which means we start counting at 0. /// position is 0-based, which means we start counting at 0.
pub fn pos(&self) -> (u16, u16) { pub fn pos(&self) -> Result<(u16, u16)> {
self.cursor.pos() self.cursor.pos()
} }
/// Move the current cursor position `n` times up. /// Move the current cursor position `n` times up.
pub fn move_up(&mut self, count: u16) -> &mut TerminalCursor { pub fn move_up(&mut self, count: u16) -> Result<&mut TerminalCursor> {
self.cursor.move_up(count).unwrap(); self.cursor.move_up(count)?;
self Ok(self)
} }
/// Move the current cursor position `n` times right. /// Move the current cursor position `n` times right.
pub fn move_right(&mut self, count: u16) -> &mut TerminalCursor { pub fn move_right(&mut self, count: u16) -> Result<&mut TerminalCursor> {
self.cursor.move_right(count).unwrap(); self.cursor.move_right(count)?;
self Ok(self)
} }
/// Move the current cursor position `n` times down. /// Move the current cursor position `n` times down.
pub fn move_down(&mut self, count: u16) -> &mut TerminalCursor { pub fn move_down(&mut self, count: u16) -> Result<&mut TerminalCursor> {
self.cursor.move_down(count).unwrap(); self.cursor.move_down(count)?;
self Ok(self)
} }
/// Move the current cursor position `n` times left. /// Move the current cursor position `n` times left.
pub fn move_left(&mut self, count: u16) -> &mut TerminalCursor { pub fn move_left(&mut self, count: u16) -> Result<&mut TerminalCursor> {
self.cursor.move_left(count).unwrap(); self.cursor.move_left(count).unwrap();
self Ok(self)
} }
/// Save cursor position for recall later. /// Save cursor position for recall later.

View File

@ -24,31 +24,31 @@ impl ITerminalCursor for WinApiCursor {
Ok(()) Ok(())
} }
fn pos(&self) -> (u16, u16) { fn pos(&self) -> Result<(u16, u16)> {
let cursor = Cursor::new().unwrap(); let cursor = Cursor::new()?;
cursor.position().map(Into::into).unwrap_or((0, 0)) Ok(cursor.position()?.into())
} }
fn move_up(&self, count: u16) -> Result<()> { fn move_up(&self, count: u16) -> Result<()> {
let (xpos, ypos) = self.pos(); let (xpos, ypos) = self.pos()?;
self.goto(xpos, ypos - count)?; self.goto(xpos, ypos - count)?;
Ok(()) Ok(())
} }
fn move_right(&self, count: u16) -> Result<()> { fn move_right(&self, count: u16) -> Result<()> {
let (xpos, ypos) = self.pos(); let (xpos, ypos) = self.pos()?;
self.goto(xpos + count, ypos)?; self.goto(xpos + count, ypos)?;
Ok(()) Ok(())
} }
fn move_down(&self, count: u16) -> Result<()> { fn move_down(&self, count: u16) -> Result<()> {
let (xpos, ypos) = self.pos(); let (xpos, ypos) = self.pos()?;
self.goto(xpos, ypos + count)?; self.goto(xpos, ypos + count)?;
Ok(()) Ok(())
} }
fn move_left(&self, count: u16) -> Result<()> { fn move_left(&self, count: u16) -> Result<()> {
let (xpos, ypos) = self.pos(); let (xpos, ypos) = self.pos()?;
self.goto(xpos - count, ypos)?; self.goto(xpos - count, ypos)?;
Ok(()) Ok(())
} }
@ -87,7 +87,9 @@ mod tests {
let cursor = WinApiCursor::new(); let cursor = WinApiCursor::new();
assert!(cursor.goto(5, 5).is_ok()); assert!(cursor.goto(5, 5).is_ok());
let (x, y) = cursor.pos(); let pos = cursor.pos();
assert!(pos.is_ok());
let (x, y) = pos.unwrap();
assert_eq!(x, 5); assert_eq!(x, 5);
assert_eq!(y, 5); assert_eq!(y, 5);
@ -96,13 +98,18 @@ mod tests {
#[test] #[test]
fn reset_safe_winapi() { fn reset_safe_winapi() {
let cursor = WinApiCursor::new(); let cursor = WinApiCursor::new();
let (x, y) = cursor.pos();
let pos = cursor.pos();
assert!(pos.is_ok());
let (x, y) = pos.unwrap();
assert!(cursor.save_position().is_ok()); assert!(cursor.save_position().is_ok());
assert!(cursor.goto(5, 5).is_ok()); assert!(cursor.goto(5, 5).is_ok());
assert!(cursor.reset_position().is_ok()); assert!(cursor.reset_position().is_ok());
let (x_saved, y_saved) = cursor.pos(); let pos = cursor.pos();
assert!(pos.is_ok());
let (x_saved, y_saved) = pos.unwrap();
assert_eq!(x, x_saved); assert_eq!(x, x_saved);
assert_eq!(y, y_saved); assert_eq!(y, y_saved);

View File

@ -7,11 +7,11 @@ use crossterm_utils::{
}; };
#[cfg(unix)] #[cfg(unix)]
pub fn get_cursor_position() -> (u16, u16) { pub fn get_cursor_position() -> Result<(u16, u16)> {
if unsafe { RAW_MODE_ENABLED } { if unsafe { RAW_MODE_ENABLED } {
pos_raw().unwrap_or((0, 0)) pos_raw()
} else { } else {
pos().unwrap_or((0, 0)) pos()
} }
} }
@ -45,33 +45,17 @@ pub fn pos_raw() -> Result<(u16, u16)> {
stdin.lock().read_until(b'[', &mut vec![])?; stdin.lock().read_until(b'[', &mut vec![])?;
let mut rows = vec![]; let mut rows = vec![];
stdin.lock().read_until(b';', &mut rows).unwrap(); stdin.lock().read_until(b';', &mut rows)?;
let mut cols = vec![]; let mut cols = vec![];
stdin.lock().read_until(b'R', &mut cols).unwrap(); stdin.lock().read_until(b'R', &mut cols)?;
// remove delimiter // remove delimiter
rows.pop(); rows.pop();
cols.pop(); cols.pop();
let rows = rows let rows = String::from_utf8(rows)?.parse::<u16>()?;
.into_iter() let cols = String::from_utf8(cols)?.parse::<u16>()?;
.map(|b| (b as char))
.fold(String::new(), |mut acc, n| {
acc.push(n);
acc
})
.parse::<usize>()
.unwrap();
let cols = cols
.into_iter()
.map(|b| (b as char))
.fold(String::new(), |mut acc, n| {
acc.push(n);
acc
})
.parse::<usize>()
.unwrap();
Ok(((cols - 1) as u16, (rows - 1) as u16)) Ok((cols - 1, rows - 1))
} }

View File

@ -12,12 +12,9 @@ use crossterm_utils::Result;
pub use crossterm_winapi::{is_true, Coord, Handle, HandleType, ScreenBuffer}; pub use crossterm_winapi::{is_true, Coord, Handle, HandleType, ScreenBuffer};
#[cfg(windows)] #[cfg(windows)]
pub fn get_cursor_position() -> (u16, u16) { pub fn get_cursor_position() -> Result<(u16, u16)> {
if let Ok(cursor) = Cursor::new() { let cursor = Cursor::new()?;
cursor.position().unwrap().into() Ok(cursor.position()?.into())
} else {
(0, 0)
}
} }
#[cfg(windows)] #[cfg(windows)]

View File

@ -90,26 +90,26 @@ use crossterm::terminal::{terminal,ClearType};
let mut terminal = terminal(); let mut terminal = terminal();
// Clear all lines in terminal; // Clear all lines in terminal;
terminal.clear(ClearType::All); terminal.clear(ClearType::All)?;
// Clear all cells from current cursor position down. // Clear all cells from current cursor position down.
terminal.clear(ClearType::FromCursorDown); terminal.clear(ClearType::FromCursorDown)?;
// Clear all cells from current cursor position down. // Clear all cells from current cursor position down.
terminal.clear(ClearType::FromCursorUp); terminal.clear(ClearType::FromCursorUp)?;
// Clear current line cells. // Clear current line cells.
terminal.clear(ClearType::CurrentLine); terminal.clear(ClearType::CurrentLine)?;
// Clear all the cells until next line. // Clear all the cells until next line.
terminal.clear(ClearType::UntilNewLine); terminal.clear(ClearType::UntilNewLine)?;
// Get terminal size // Get terminal size
let (width, height) = terminal.terminal_size(); let (width, height) = terminal.size()?;
print!("X: {}, y: {}", width, height); print!("X: {}, y: {}", width, height);
// Scroll down, up 10 lines. // Scroll down, up 10 lines.
terminal.scroll_down(10); terminal.scroll_down(10)?;
terminal.scroll_up(10); terminal.scroll_up(10)?;
// Set terminal size (width, height) // Set terminal size (width, height)
terminal.set_size(10,10); terminal.set_size(10,10)?;
// exit the current process. // exit the current process.
terminal.exit(); terminal.exit();

View File

@ -1,11 +1,13 @@
use libc::{ioctl, winsize, STDOUT_FILENO, TIOCGWINSZ}; use libc::{ioctl, winsize, STDOUT_FILENO, TIOCGWINSZ};
use crossterm_utils::Result;
pub fn exit() { pub fn exit() {
::std::process::exit(0); ::std::process::exit(0);
} }
/// Get the current terminal size. /// Get the current terminal size.
pub fn get_terminal_size() -> (u16, u16) { pub fn get_terminal_size() -> Result<(u16, u16)> {
// http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc // http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc
let mut size = winsize { let mut size = winsize {
ws_row: 0, ws_row: 0,
@ -16,8 +18,8 @@ pub fn get_terminal_size() -> (u16, u16) {
let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ.into(), &mut size) }; let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ.into(), &mut size) };
if r == 0 { if r == 0 {
(size.ws_col, size.ws_row) Ok((size.ws_col, size.ws_row))
} else { } else {
(0, 0) Err(std::io::Error::last_os_error().into())
} }
} }

View File

@ -1,3 +1,4 @@
use crossterm_utils::Result;
use crossterm_winapi::ScreenBuffer; use crossterm_winapi::ScreenBuffer;
/// Exit the current process. /// Exit the current process.
@ -6,11 +7,7 @@ pub fn exit() {
} }
#[cfg(windows)] #[cfg(windows)]
pub fn get_terminal_size() -> (u16, u16) { pub fn get_terminal_size() -> Result<(u16, u16)> {
if let Ok(buffer) = ScreenBuffer::current() { let buffer = ScreenBuffer::current()?;
let size = buffer.info().unwrap().terminal_size(); Ok(buffer.info()?.terminal_size().into())
((size.width + 1) as u16, (size.height + 1) as u16)
} else {
(0, 0)
}
} }

View File

@ -43,11 +43,11 @@ trait ITerminal {
/// Clear the current cursor by specifying the clear type /// Clear the current cursor by specifying the clear type
fn clear(&self, clear_type: ClearType) -> Result<()>; fn clear(&self, clear_type: ClearType) -> Result<()>;
/// Get the terminal size (x,y) /// Get the terminal size (x,y)
fn terminal_size(&self) -> (u16, u16); fn size(&self) -> Result<(u16, u16)>;
/// Scroll `n` lines up in the current terminal. /// Scroll `n` lines up in the current terminal.
fn scroll_up(&self, count: i16) -> Result<()>; fn scroll_up(&self, count: u16) -> Result<()>;
/// Scroll `n` lines down in the current terminal. /// Scroll `n` lines down in the current terminal.
fn scroll_down(&self, count: i16) -> Result<()>; fn scroll_down(&self, count: u16) -> Result<()>;
/// Resize terminal to the given width and height. /// Resize terminal to the given width and height.
fn set_size(&self, width: i16, height: i16) -> Result<()>; fn set_size(&self, width: u16, height: u16) -> Result<()>;
} }

View File

@ -15,17 +15,17 @@ pub static CLEAR_FROM_CURRENT_LINE: &'static str = csi!("2K");
pub static CLEAR_UNTIL_NEW_LINE: &'static str = csi!("K"); pub static CLEAR_UNTIL_NEW_LINE: &'static str = csi!("K");
#[inline] #[inline]
pub fn get_scroll_up_ansi(count: i16) -> String { pub fn get_scroll_up_ansi(count: u16) -> String {
format!(csi!("{}S"), count) format!(csi!("{}S"), count)
} }
#[inline] #[inline]
pub fn get_scroll_down_ansi(count: i16) -> String { pub fn get_scroll_down_ansi(count: u16) -> String {
format!(csi!("{}T"), count) format!(csi!("{}T"), count)
} }
#[inline] #[inline]
pub fn get_set_size_ansi(width: i16, height: i16) -> String { pub fn get_set_size_ansi(width: u16, height: u16) -> String {
format!(csi!("8;{};{}t"), height, width) format!(csi!("8;{};{}t"), height, width)
} }
@ -61,21 +61,21 @@ impl ITerminal for AnsiTerminal {
Ok(()) Ok(())
} }
fn terminal_size(&self) -> (u16, u16) { fn size(&self) -> Result<(u16, u16)> {
get_terminal_size() get_terminal_size()
} }
fn scroll_up(&self, count: i16) -> Result<()> { fn scroll_up(&self, count: u16) -> Result<()> {
write_cout!(get_scroll_up_ansi(count))?; write_cout!(get_scroll_up_ansi(count))?;
Ok(()) Ok(())
} }
fn scroll_down(&self, count: i16) -> Result<()> { fn scroll_down(&self, count: u16) -> Result<()> {
write_cout!(get_scroll_down_ansi(count))?; write_cout!(get_scroll_down_ansi(count))?;
Ok(()) Ok(())
} }
fn set_size(&self, width: i16, height: i16) -> Result<()> { fn set_size(&self, width: u16, height: u16) -> Result<()> {
write_cout!(get_set_size_ansi(width, height))?; write_cout!(get_set_size_ansi(width, height))?;
Ok(()) Ok(())
} }
@ -100,7 +100,9 @@ mod tests {
// see issue: https://github.com/eminence/terminal-size/issues/11 // see issue: https://github.com/eminence/terminal-size/issues/11
thread::sleep(time::Duration::from_millis(30)); thread::sleep(time::Duration::from_millis(30));
let (x, y) = terminal.terminal_size(); let size = terminal.size();
assert!(size.is_ok());
let (x, y) = size.unwrap();
assert_eq!(x, 50); assert_eq!(x, 50);
assert_eq!(y, 50); assert_eq!(y, 50);

View File

@ -70,19 +70,16 @@ impl Terminal {
self.terminal.clear(clear_type) self.terminal.clear(clear_type)
} }
/// Get the terminal size (x,y). /// Get the terminal size `(x,y)`.
/// pub fn size(&self) -> Result<(u16, u16)> {
/// # Remark self.terminal.size()
/// This will return a tuple of (x: u16, y: u16)
pub fn terminal_size(&self) -> (u16, u16) {
self.terminal.terminal_size()
} }
/// Scroll `n` lines up in the current terminal. /// Scroll `n` lines up in the current terminal.
/// ///
/// # Parameter /// # Parameter
/// - `count`: the number of rows should be shifted up. /// - `count`: the number of rows should be shifted up.
pub fn scroll_up(&self, count: i16) -> Result<()> { pub fn scroll_up(&self, count: u16) -> Result<()> {
self.terminal.scroll_up(count) self.terminal.scroll_up(count)
} }
@ -90,7 +87,7 @@ impl Terminal {
/// ///
/// # Parameter /// # Parameter
/// - `count`: the number of rows should be shifted down. /// - `count`: the number of rows should be shifted down.
pub fn scroll_down(&self, count: i16) -> Result<()> { pub fn scroll_down(&self, count: u16) -> Result<()> {
self.terminal.scroll_down(count) self.terminal.scroll_down(count)
} }
@ -103,7 +100,7 @@ impl Terminal {
/// // Set of the size to X: 10 and Y: 10 /// // Set of the size to X: 10 and Y: 10
/// let size = term.set_size(10,10); /// let size = term.set_size(10,10);
/// ``` /// ```
pub fn set_size(&self, width: i16, height: i16) -> Result<()> { pub fn set_size(&self, width: u16, height: u16) -> Result<()> {
self.terminal.set_size(width, height) self.terminal.set_size(width, height)
} }
@ -143,7 +140,7 @@ pub fn terminal() -> Terminal {
/// When executed, this command will scroll up the terminal buffer by the given number of times. /// When executed, this command will scroll up the terminal buffer by the given number of times.
/// ///
/// See `crossterm/examples/command.rs` for more information on how to execute commands. /// See `crossterm/examples/command.rs` for more information on how to execute commands.
pub struct ScrollUp(pub i16); pub struct ScrollUp(pub u16);
impl Command for ScrollUp { impl Command for ScrollUp {
type AnsiType = String; type AnsiType = String;
@ -161,7 +158,7 @@ impl Command for ScrollUp {
/// When executed, this command will scroll down the terminal buffer by the given number of times. /// When executed, this command will scroll down the terminal buffer by the given number of times.
/// ///
/// See `crossterm/examples/command.rs` for more information on how to execute commands. /// See `crossterm/examples/command.rs` for more information on how to execute commands.
pub struct ScrollDown(pub i16); pub struct ScrollDown(pub u16);
impl Command for ScrollDown { impl Command for ScrollDown {
type AnsiType = String; type AnsiType = String;
@ -209,7 +206,7 @@ impl Command for Clear {
/// When executed, this command will set the terminal sie to the given (`width` and `height`) /// When executed, this command will set the terminal sie to the given (`width` and `height`)
/// ///
/// See `crossterm/examples/command.rs` for more information on how to execute commands. /// See `crossterm/examples/command.rs` for more information on how to execute commands.
pub struct SetSize(pub i16, pub i16); pub struct SetSize(pub u16, pub u16);
impl Command for SetSize { impl Command for SetSize {
type AnsiType = String; type AnsiType = String;

View File

@ -41,15 +41,16 @@ impl ITerminal for WinApiTerminal {
Ok(()) Ok(())
} }
fn terminal_size(&self) -> (u16, u16) { fn size(&self) -> Result<(u16, u16)> {
get_terminal_size() get_terminal_size()
} }
fn scroll_up(&self, count: i16) -> Result<()> { fn scroll_up(&self, count: u16) -> Result<()> {
let csbi = ScreenBuffer::current()?; let csbi = ScreenBuffer::current()?;
let mut window = csbi.info()?.terminal_window(); let mut window = csbi.info()?.terminal_window();
// Check whether the window is too close to the screen buffer top // Check whether the window is too close to the screen buffer top
let count = count as i16;
if window.top >= count { if window.top >= count {
window.top -= count; // move top down window.top -= count; // move top down
window.bottom = count; // move bottom down window.bottom = count; // move bottom down
@ -59,13 +60,14 @@ impl ITerminal for WinApiTerminal {
Ok(()) Ok(())
} }
fn scroll_down(&self, count: i16) -> Result<()> { fn scroll_down(&self, count: u16) -> Result<()> {
let screen_buffer = ScreenBuffer::current()?; let screen_buffer = ScreenBuffer::current()?;
let csbi = screen_buffer.info()?; let csbi = screen_buffer.info()?;
let mut window = csbi.terminal_window(); let mut window = csbi.terminal_window();
let buffer_size = csbi.buffer_size(); let buffer_size = csbi.buffer_size();
// Check whether the window is too close to the screen buffer top // Check whether the window is too close to the screen buffer top
let count = count as i16;
if window.bottom < buffer_size.height - count { if window.bottom < buffer_size.height - count {
window.top += count; // move top down window.top += count; // move top down
window.bottom += count; // move bottom down window.bottom += count; // move bottom down
@ -76,7 +78,7 @@ impl ITerminal for WinApiTerminal {
} }
/// Set the current terminal size /// Set the current terminal size
fn set_size(&self, width: i16, height: i16) -> Result<()> { fn set_size(&self, width: u16, height: u16) -> Result<()> {
if width <= 0 { if width <= 0 {
return Err(ErrorKind::ResizingTerminalFailure(String::from( return Err(ErrorKind::ResizingTerminalFailure(String::from(
"Cannot set the terminal width lower than 1", "Cannot set the terminal width lower than 1",
@ -103,6 +105,7 @@ impl ITerminal for WinApiTerminal {
// buffer to be large enough. Include window position. // buffer to be large enough. Include window position.
let mut resize_buffer = false; let mut resize_buffer = false;
let width = width as i16;
if current_size.width < window.left + width { if current_size.width < window.left + width {
if window.left >= i16::max_value() - width { if window.left >= i16::max_value() - width {
return Err(ErrorKind::ResizingTerminalFailure(String::from( return Err(ErrorKind::ResizingTerminalFailure(String::from(
@ -113,6 +116,7 @@ impl ITerminal for WinApiTerminal {
new_size.width = window.left + width; new_size.width = window.left + width;
resize_buffer = true; resize_buffer = true;
} }
let height = height as i16;
if current_size.height < window.top + height { if current_size.height < window.top + height {
if window.top >= i16::max_value() - height { if window.top >= i16::max_value() - height {
return Err(ErrorKind::ResizingTerminalFailure(String::from( return Err(ErrorKind::ResizingTerminalFailure(String::from(
@ -284,7 +288,9 @@ mod tests {
assert!(terminal.set_size(30, 30).is_ok()); assert!(terminal.set_size(30, 30).is_ok());
let (x, y) = terminal.terminal_size(); let size = terminal.size();
assert!(size.is_ok());
let (x, y) = size.unwrap();
assert_eq!(x, 30); assert_eq!(x, 30);
assert_eq!(y, 30); assert_eq!(y, 30);

View File

@ -13,6 +13,8 @@ pub type Result<T> = std::result::Result<T, ErrorKind>;
pub enum ErrorKind { pub enum ErrorKind {
IoError(io::Error), IoError(io::Error),
FmtError(fmt::Error), FmtError(fmt::Error),
Utf8Error(std::string::FromUtf8Error),
ParseIntError(std::num::ParseIntError),
ResizingTerminalFailure(String), ResizingTerminalFailure(String),
#[doc(hidden)] #[doc(hidden)]
@ -49,3 +51,15 @@ impl From<fmt::Error> for ErrorKind {
ErrorKind::FmtError(e) ErrorKind::FmtError(e)
} }
} }
impl From<std::string::FromUtf8Error> for ErrorKind {
fn from(e: std::string::FromUtf8Error) -> Self {
ErrorKind::Utf8Error(e)
}
}
impl From<std::num::ParseIntError> for ErrorKind {
fn from(e: std::num::ParseIntError) -> Self {
ErrorKind::ParseIntError(e)
}
}

View File

@ -17,14 +17,14 @@ impl ScreenBufferInfo {
/// This will return the buffer size. /// This will return the buffer size.
/// ///
/// Will take `dwSize`from the current screen buffer and convert it into the `Size`. /// Will take `dwSize` from the current screen buffer and convert it into the `Size`.
pub fn buffer_size(&self) -> Size { pub fn buffer_size(&self) -> Size {
Size::from(self.0.dwSize) Size::from(self.0.dwSize)
} }
/// This will return the terminal size. /// This will return the terminal size.
/// ///
/// Will calculate the whit and height from `srWindow` and convert it into a `Size`. /// Will calculate the width and height from `srWindow` and convert it into a `Size`.
pub fn terminal_size(&self) -> Size { pub fn terminal_size(&self) -> Size {
(Size::new( (Size::new(
self.0.srWindow.Right - self.0.srWindow.Left, self.0.srWindow.Right - self.0.srWindow.Left,

View File

@ -6,10 +6,10 @@ use crossterm::{
Terminal, TerminalCursor, Terminal, TerminalCursor,
}; };
fn log(input_buf: Arc<Mutex<String>>) -> Vec<thread::JoinHandle<()>> { fn log(input_buf: Arc<Mutex<String>>) -> Result<Vec<thread::JoinHandle<()>>> {
let mut threads = Vec::with_capacity(10); let mut threads = Vec::with_capacity(10);
let (_, term_height) = terminal().terminal_size(); let (_, term_height) = terminal().size()?;
for i in 0..1 { for i in 0..1 {
let input_buffer = input_buf.clone(); let input_buffer = input_buf.clone();
@ -37,7 +37,7 @@ fn log(input_buf: Arc<Mutex<String>>) -> Vec<thread::JoinHandle<()>> {
threads.push(join); threads.push(join);
} }
threads Ok(threads)
} }
fn swap_write( fn swap_write(
@ -60,7 +60,7 @@ fn main() -> Result<()> {
let input_buf = Arc::new(Mutex::new(String::new())); let input_buf = Arc::new(Mutex::new(String::new()));
let threads = log(input_buf.clone()); let threads = log(input_buf.clone())?;
let mut count = 0; let mut count = 0;

View File

@ -17,36 +17,48 @@ fn goto() -> Result<()> {
} }
/// get the cursor position /// get the cursor position
fn pos() { fn pos() -> Result<()> {
// Get the cursor // Get the cursor
let cursor = cursor(); let cursor = cursor();
// get the cursor position. // get the cursor position.
let (x, y) = cursor.pos(); let (x, y) = cursor.pos()?;
println!("{} {}", x, y); println!("{} {}", x, y);
Ok(())
} }
/// Move the cursor 3 up | demonstration. /// Move the cursor 3 up | demonstration.
fn move_up() { fn move_up() -> Result<()> {
// Get the cursor // Get the cursor
let mut cursor = cursor(); let mut cursor = cursor();
// Move the cursor to position 3 times to the up in the terminal // Move the cursor to position 3 times to the up in the terminal
cursor.move_up(10); cursor.move_up(3)?;
} Ok(())
/// Move the cursor 3 to the right | demonstration.
fn move_right() {
let mut cursor = cursor();
// Move the cursor to position 3 times to the right in the terminal
cursor.move_right(3);
} }
/// Move the cursor 3 down | demonstration. /// Move the cursor 3 down | demonstration.
fn move_down() { fn move_down() -> Result<()> {
let mut cursor = cursor(); let mut cursor = cursor();
// Move the cursor to position 3 times to the down in the terminal // Move the cursor to position 3 times to the down in the terminal
cursor.move_down(3); cursor.move_down(3)?;
Ok(())
}
/// Move the cursor 3 to the right | demonstration.
fn move_right() -> Result<()> {
let mut cursor = cursor();
// Move the cursor to position 3 times to the right in the terminal
cursor.move_right(3)?;
Ok(())
}
/// Move the cursor 3 left | demonstration.
fn move_left() -> Result<()> {
let mut cursor = cursor();
// Move the cursor to position 3 times to the left in the terminal
cursor.move_left(3)?;
Ok(())
} }
/// Save and reset cursor position | demonstration.. /// Save and reset cursor position | demonstration..

View File

@ -34,7 +34,7 @@ pub enum Event {
fn main() -> Result<()> { fn main() -> Result<()> {
// Print the welcome screen and ask for the map size. // Print the welcome screen and ask for the map size.
let crossterm = Crossterm::new(); let crossterm = Crossterm::new();
let (map_width, map_height) = ask_for_map_size(crossterm.terminal().terminal_size())?; let (map_width, map_height) = ask_for_map_size(crossterm.terminal().size()?)?;
// Switch screen to the raw mode to avoid printing key presses on the screen // Switch screen to the raw mode to avoid printing key presses on the screen
// and hide the cursor. // and hide the cursor.

View File

@ -75,14 +75,15 @@ fn clear_until_new_line() -> Result<()> {
} }
/// Print the the current terminal size | demonstration. /// Print the the current terminal size | demonstration.
fn print_terminal_size() { fn print_terminal_size() -> Result<()> {
let terminal = terminal(); let terminal = terminal();
// Get terminal size // Get terminal size
let (width, height) = terminal.terminal_size(); let (width, height) = terminal.size()?;
// Print results // Print results
print!("X: {}, y: {}", width, height); print!("X: {}, y: {}", width, height);
Ok(())
} }
/// Set the terminal size to width 10, height: 10 | demonstration. /// Set the terminal size to width 10, height: 10 | demonstration.

13
scripts/test-examples.sh Executable file
View File

@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -ev
pushd examples/program_examples
for d in */ ; do
pushd "$d"
cargo build
if [ "$TRAVIS_RUST_VERSION" = "stable" ]; then
cargo fmt --all -- --check
fi
popd
done
popd