aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2016-04-27 01:50:04 -0400
committerJesse Luehrs <doy@tozt.net>2016-04-27 01:50:36 -0400
commit85213a843566b82b05626efd97c48644b04935d2 (patch)
tree1897cb51bd0519aa955310ca049a09064e9a476d
parentf0486657754c485f8211c6d00f9bf5ba6953dd67 (diff)
downloadvt100-rust-85213a843566b82b05626efd97c48644b04935d2.tar.gz
vt100-rust-85213a843566b82b05626efd97c48644b04935d2.zip
start implementing cells
-rw-r--r--src/cell.rs30
-rw-r--r--src/ffi.rs6
-rw-r--r--src/lib.rs2
-rw-r--r--src/screen.rs12
-rw-r--r--src/types.rs1
-rw-r--r--tests/basic.rs14
6 files changed, 65 insertions, 0 deletions
diff --git a/src/cell.rs b/src/cell.rs
new file mode 100644
index 0000000..7590e98
--- /dev/null
+++ b/src/cell.rs
@@ -0,0 +1,30 @@
+use libc;
+use std;
+
+use types;
+
+pub struct Cell(*mut types::CellImpl);
+
+#[repr(C)]
+struct CellPrefix {
+ pub contents: [libc::c_char; 8],
+ pub len: libc::size_t,
+}
+
+impl Cell {
+ pub fn new(cell_impl: *mut types::CellImpl) -> Cell {
+ Cell(cell_impl)
+ }
+
+ pub fn contents(&self) -> &str {
+ let Cell(cell_impl) = *self;
+ let contents: &[u8] = unsafe {
+ let prefix: *mut CellPrefix = std::mem::transmute(cell_impl);
+ std::slice::from_raw_parts(
+ &(*prefix).contents as *const i8 as *const u8,
+ (*prefix).len
+ )
+ };
+ std::str::from_utf8(contents).unwrap()
+ }
+}
diff --git a/src/ffi.rs b/src/ffi.rs
index 1b984b5..e498361 100644
--- a/src/ffi.rs
+++ b/src/ffi.rs
@@ -32,6 +32,12 @@ extern "C" {
rows: libc::c_int,
);
+ pub fn vt100_screen_cell_at(
+ screen: *mut types::ScreenImpl,
+ row: libc::c_int,
+ col: libc::c_int,
+ ) -> *mut types::CellImpl;
+
pub fn vt100_wrapper_rows(screen: *mut types::ScreenImpl) -> libc::c_int;
pub fn vt100_wrapper_cols(screen: *mut types::ScreenImpl) -> libc::c_int;
}
diff --git a/src/lib.rs b/src/lib.rs
index 71fc540..aa7d488 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,7 +1,9 @@
extern crate libc;
+mod cell;
mod ffi;
mod screen;
mod types;
pub use screen::Screen;
+pub use cell::Cell;
diff --git a/src/screen.rs b/src/screen.rs
index da96a6a..d3e026f 100644
--- a/src/screen.rs
+++ b/src/screen.rs
@@ -1,6 +1,7 @@
use libc;
use std;
+use cell;
use ffi;
use types;
@@ -91,6 +92,17 @@ impl Screen {
}.to_vec();
std::string::String::from_utf8(rust_plaintext).unwrap()
}
+
+ pub fn cell(&self, row: i32, col: i32) -> Option<cell::Cell> {
+ let Screen(screen_impl) = *self;
+ if row < 0 || row >= self.rows() || col < 0 || col >= self.cols() {
+ return None
+ }
+ let cell_impl = unsafe {
+ ffi::vt100_screen_cell_at(screen_impl, row, col)
+ };
+ Some(cell::Cell::new(cell_impl))
+ }
}
impl Drop for Screen {
diff --git a/src/types.rs b/src/types.rs
index a5ac590..fca7f97 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,6 +1,7 @@
use libc;
pub enum ScreenImpl {}
+pub enum CellImpl {}
#[repr(C)]
pub struct Loc {
diff --git a/tests/basic.rs b/tests/basic.rs
index 7312928..27b688d 100644
--- a/tests/basic.rs
+++ b/tests/basic.rs
@@ -25,4 +25,18 @@ mod tests {
assert_eq!(screen.rows(), 34);
assert_eq!(screen.cols(), 8);
}
+
+ #[test]
+ fn cell_contents() {
+ let mut screen = vt100::Screen::new(24, 80);
+ let input = b"foo\x1b[31m\x1b[32mb\x1b[3;7;42ma\x1b[23mr";
+ screen.process(input);
+ assert_eq!(screen.cell(0, 0).unwrap().contents(), "f");
+ assert_eq!(screen.cell(0, 1).unwrap().contents(), "o");
+ assert_eq!(screen.cell(0, 2).unwrap().contents(), "o");
+ assert_eq!(screen.cell(0, 3).unwrap().contents(), "b");
+ assert_eq!(screen.cell(0, 4).unwrap().contents(), "a");
+ assert_eq!(screen.cell(0, 5).unwrap().contents(), "r");
+ assert_eq!(screen.cell(0, 6).unwrap().contents(), "");
+ }
}