diff --git a/Cargo.toml b/Cargo.toml index 6096b7d..781c89b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,5 +31,8 @@ winapi = { version = "0.3", features = [ "consoleapi", "handleapi", "minwindef", "ntdef", "processenv", "synchapi", "winbase", "wincon", "winerror", "winnt", "winuser" ] } +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen = "0.2" + [dev-dependencies] rand = "0.7" diff --git a/src/lib.rs b/src/lib.rs index 2f641d3..52be4f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,7 @@ //! [`term_write!`]: macro.term_write.html //! [`term_writeln!`]: macro.term_writeln.html +#![allow(unused_imports)] #![deny(missing_docs)] #[macro_use] extern crate bitflags; @@ -69,6 +70,10 @@ mod sys; #[path = "windows/mod.rs"] mod sys; +#[cfg(target_arch = "wasm32")] +#[path = "wasm32/mod.rs"] +mod sys; + #[cfg(unix)] pub use crate::sys::ext as unix; diff --git a/src/wasm32/ext.rs b/src/wasm32/ext.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/wasm32/mod.rs b/src/wasm32/mod.rs new file mode 100644 index 0000000..d81cc4c --- /dev/null +++ b/src/wasm32/mod.rs @@ -0,0 +1,11 @@ +pub use self::screen::{ + Screen, ScreenReadGuard, ScreenWriteGuard, +}; +pub use self::terminal::{ + PrepareState, + Terminal, TerminalReadGuard, TerminalWriteGuard, +}; + +pub mod ext; +mod screen; +mod terminal; diff --git a/src/wasm32/screen.rs b/src/wasm32/screen.rs new file mode 100644 index 0000000..25e1013 --- /dev/null +++ b/src/wasm32/screen.rs @@ -0,0 +1,163 @@ +use std::io; +use std::sync::{LockResult, Mutex, MutexGuard, TryLockResult}; +use std::time::Duration; + +use crate::buffer::ScreenBuffer; +use crate::priv_util::{ + map2_lock_result, map2_try_lock_result, map_lock_result, map_try_lock_result, +}; +use crate::sys::{PrepareState, Terminal, TerminalReadGuard, TerminalWriteGuard}; +use crate::terminal::{Color, Cursor, CursorMode, Event, PrepareConfig, Size, Style}; + +pub struct Screen { + term: Terminal, + + state: Option, + writer: Mutex, +} + +pub struct ScreenReadGuard<'a> { + screen: &'a Screen, + reader: TerminalReadGuard<'a>, +} + +pub struct ScreenWriteGuard<'a> { + writer: TerminalWriteGuard<'a>, + data: MutexGuard<'a, Writer>, +} + +struct Writer { + buffer: ScreenBuffer, + clear_screen: bool, + real_cursor: Cursor, +} + +impl Screen { + pub fn new(term: Terminal, config: PrepareConfig) -> io::Result { + todo!() + } + + pub fn stdout(config: PrepareConfig) -> io::Result { + Screen::new(Terminal::stdout()?, config) + } + + pub fn stderr(config: PrepareConfig) -> io::Result { + Screen::new(Terminal::stderr()?, config) + } + + forward_screen_buffer_methods!{ |slf| slf.lock_write_data().buffer } + + pub fn lock_read(&self) -> LockResult { + todo!() + } + + pub fn try_lock_read(&self) -> TryLockResult { + todo!() + } + + pub fn lock_write(&self) -> LockResult { + todo!() + } + + pub fn try_lock_write(&self) -> TryLockResult { + todo!() + } + + fn lock_reader(&self) -> ScreenReadGuard { + todo!() + } + + fn lock_writer(&self) -> ScreenWriteGuard { + todo!() + } + + fn lock_write_data(&self) -> MutexGuard { + todo!() + } + + pub fn name(&self) -> &str { + todo!() + } + + pub fn set_cursor_mode(&self, mode: CursorMode) -> io::Result<()> { + todo!() + } + + pub fn wait_event(&self, timeout: Option) -> io::Result { + todo!() + } + + pub fn read_event(&self, timeout: Option) -> io::Result> { + todo!() + } + + pub fn read_raw(&self, buf: &mut [u8], timeout: Option) -> io::Result> { + todo!() + } + + pub fn refresh(&self) -> io::Result<()> { + todo!() + } +} + +impl Drop for Screen { + fn drop(&mut self) { + todo!() + } +} +impl<'a> ScreenReadGuard<'a> { + fn new(screen: &'a Screen, reader: TerminalReadGuard<'a>) -> ScreenReadGuard<'a> { + todo!() + } + + pub fn wait_event(&mut self, timeout: Option) -> io::Result { + todo!() + } + + pub fn read_event(&mut self, timeout: Option) -> io::Result> { + todo!() + } + + pub fn read_raw(&mut self, buf: &mut [u8], timeout: Option) -> io::Result> { + todo!() + } +} + +impl<'a> ScreenWriteGuard<'a> { + fn new(writer: TerminalWriteGuard<'a>, data: MutexGuard<'a, Writer>) + -> ScreenWriteGuard<'a> { + todo!() + } + + forward_screen_buffer_mut_methods!{ |slf| slf.data.buffer } + + pub fn set_cursor_mode(&mut self, mode: CursorMode) -> io::Result<()> { + todo!() + } + + pub fn refresh(&mut self) -> io::Result<()> { + todo!() + } + + fn move_cursor(&mut self, pos: Cursor) -> io::Result<()> { + todo!() + } + + fn apply_attrs(&mut self, + (fg, bg, style): (Option, Option, Style)) + -> io::Result<()> { + todo!() + } +} + +impl<'a> Drop for ScreenWriteGuard<'a> { + fn drop(&mut self) { + todo!() + } +} + +impl Writer { + fn update_size(&mut self, new_size: Size) { + todo!() + } +} diff --git a/src/wasm32/terminal.rs b/src/wasm32/terminal.rs new file mode 100644 index 0000000..9e6b508 --- /dev/null +++ b/src/wasm32/terminal.rs @@ -0,0 +1,444 @@ +use std::convert::TryFrom; +use std::io; +use std::mem::{replace, zeroed}; +use std::path::Path; +use std::str::from_utf8; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{LockResult, Mutex, MutexGuard, TryLockResult}; +use std::time::Duration; + +use smallstr::SmallString; + +use crate::priv_util::{map_lock_result, map_try_lock_result}; +use crate::sequence::{FindResult, SequenceMap}; +use crate::signal::{Signal, SignalSet}; +use crate::terminal::{ + Color, Cursor, CursorMode, Event, Key, ModifierState, MouseButton, MouseEvent, MouseInput, + PrepareConfig, Size, Style, Theme, +}; +use crate::util::prefixes; + +type SeqMap = SequenceMap, SeqData>; + +#[derive(Copy, Clone)] +enum SeqData { + XTermMouse, + Key(Key), +} + +pub struct Terminal { + sequences: SeqMap, + reader: Mutex, + writer: Mutex, +} + +pub struct TerminalReadGuard<'a> { + term: &'a Terminal, + reader: MutexGuard<'a, Reader>, +} + +pub struct TerminalWriteGuard<'a> { + term: &'a Terminal, + writer: MutexGuard<'a, Writer>, +} + +struct Reader { + in_buffer: Vec, + resume: Option, + report_signals: SignalSet, +} + +struct Writer { + out_buffer: Vec, + fg: Option, + bg: Option, + cur_style: Style, +} + +pub struct PrepareState { + restore_keypad: bool, + restore_mouse: bool, + prev_resume: Option, +} + +#[derive(Copy, Clone, Debug)] +struct Resume { + config: PrepareConfig, +} + +#[repr(C)] +struct Winsize { + ws_row: usize, + ws_col: usize, + ws_xpixel: usize, + ws_ypixel: usize, +} + +impl Terminal { + + fn new() -> io::Result { + todo!() + } + + pub fn stdout() -> io::Result { + todo!() + } + + pub fn stderr() -> io::Result { + todo!() + } + + pub fn name(&self) -> &str { + todo!() + } + + pub fn size(&self) -> io::Result { + todo!() + } + + pub fn wait_event(&self, timeout: Option) -> io::Result { + todo!() + } + + pub fn read_event(&self, timeout: Option) -> io::Result> { + todo!() + } + + pub fn read_raw(&self, buf: &mut [u8], timeout: Option) -> io::Result> { + todo!() + } + + pub fn enter_screen(&self) -> io::Result<()> { + todo!() + } + + pub fn exit_screen(&self) -> io::Result<()> { + todo!() + } + + pub fn prepare(&self, config: PrepareConfig) -> io::Result { + todo!() + } + + pub fn restore(&self, state: PrepareState) -> io::Result<()> { + todo!() + } + + pub fn clear_screen(&self) -> io::Result<()> { + todo!() + } + + pub fn clear_to_line_end(&self) -> io::Result<()> { + todo!() + } + + pub fn clear_to_screen_end(&self) -> io::Result<()> { + todo!() + } + + pub fn move_up(&self, n: usize) -> io::Result<()> { + if n != 0 { + todo!() + } + Ok(()) + } + + pub fn move_down(&self, n: usize) -> io::Result<()> { + if n != 0 { + todo!() + } + Ok(()) + } + + pub fn move_left(&self, n: usize) -> io::Result<()> { + if n != 0 { + todo!() + } + Ok(()) + } + + pub fn move_right(&self, n: usize) -> io::Result<()> { + if n != 0 { + todo!() + } + Ok(()) + } + + pub fn move_to_first_column(&self) -> io::Result<()> { + todo!() + } + + pub fn set_cursor_mode(&self, mode: CursorMode) -> io::Result<()> { + todo!() + } + + pub fn write_char(&self, ch: char) -> io::Result<()> { + todo!() + } + + pub fn write_str(&self, s: &str) -> io::Result<()> { + todo!() + } + + pub fn write_styled(&self, + fg: Option, bg: Option, style: Style, text: &str) + -> io::Result<()> { + todo!() + } + + pub fn clear_attributes(&self) -> io::Result<()> { + todo!() + } + + pub fn set_fg(&self, fg: Option) -> io::Result<()> { + todo!() + } + + pub fn set_bg(&self, bg: Option) -> io::Result<()> { + todo!() + } + + pub fn add_style(&self, style: Style) -> io::Result<()> { + todo!() + } + + pub fn remove_style(&self, style: Style) -> io::Result<()> { + todo!() + } + + pub fn set_style(&self, style: Style) -> io::Result<()> { + todo!() + } + + pub fn set_theme(&self, theme: Theme) -> io::Result<()> { + todo!() + } + + pub fn lock_read(&self) -> LockResult { + todo!() + } + + pub fn lock_write(&self) -> LockResult { + todo!() + } + + pub fn try_lock_read(&self) -> TryLockResult { + todo!() + } + + pub fn try_lock_write(&self) -> TryLockResult { + todo!() + } + + fn lock_reader(&self) -> TerminalReadGuard { + todo!() + } + + fn lock_writer(&self) -> TerminalWriteGuard { + todo!() + } +} + +impl<'a> TerminalReadGuard<'a> { + fn new(term: &'a Terminal, reader: MutexGuard<'a, Reader>) -> TerminalReadGuard<'a> { + todo!() + } + + pub fn prepare(&mut self, config: PrepareConfig) -> io::Result { + todo!() + } + + pub fn prepare_with_lock(&mut self, writer: &mut TerminalWriteGuard, + config: PrepareConfig) -> io::Result { + todo!() + } + + pub fn restore(&mut self, state: PrepareState) -> io::Result<()> { + todo!() + } + + pub fn restore_with_lock(&mut self, writer: &mut TerminalWriteGuard, + state: PrepareState) -> io::Result<()> { + todo!() + } + + pub fn wait_event(&mut self, timeout: Option) -> io::Result { + todo!() + } + + pub fn read_event(&mut self, timeout: Option) -> io::Result> { + todo!() + } + + pub fn read_raw(&mut self, buf: &mut [u8], timeout: Option) -> io::Result> { + todo!() + } + + fn read_into_buffer(&mut self, timeout: Option) -> io::Result> { + todo!() + } + + fn read_input(&mut self, buf: &mut [u8], timeout: Option) -> io::Result> { + todo!() + } + + fn try_read(&mut self) -> io::Result> { + todo!() + } + + fn handle_signal(&mut self, sig: Signal) -> io::Result> { + todo!() + } + + fn resume(&mut self) -> io::Result<()> { + todo!() + } +} + +impl<'a> TerminalWriteGuard<'a> { + fn new(term: &'a Terminal, writer: MutexGuard<'a, Writer>) -> TerminalWriteGuard<'a> { + TerminalWriteGuard{term, writer} + } + + pub fn size(&self) -> io::Result { + todo!() + } + + fn disable_keypad(&mut self) -> io::Result<()> { + todo!() + } + + fn enable_keypad(&mut self) -> io::Result { + todo!() + } + + fn disable_mouse(&mut self) -> io::Result<()> { + todo!() + } + + fn enable_mouse(&mut self, track_motion: bool) -> io::Result { + todo!() + } + + fn enter_screen(&mut self) -> io::Result<()> { + todo!() + } + + fn exit_screen(&mut self) -> io::Result<()> { + todo!() + } + + pub fn clear_attributes(&mut self) -> io::Result<()> { + todo!() + } + + pub fn set_fg(&mut self, fg: Option) -> io::Result<()> { + todo!() + } + + pub fn set_bg(&mut self, bg: Option) -> io::Result<()> { + todo!() + } + + pub fn add_style(&mut self, style: Style) -> io::Result<()> { + todo!() + } + + pub fn remove_style(&mut self, style: Style) -> io::Result<()> { + todo!() + } + + pub fn set_style(&mut self, style: Style) -> io::Result<()> { + todo!() + } + + pub fn set_theme(&mut self, theme: Theme) -> io::Result<()> { + todo!() + } + + pub fn set_attrs(&mut self, fg: Option, bg: Option, style: Style) -> io::Result<()> { + todo!() + } + + fn clear_fg(&mut self) -> io::Result<()> { + todo!() + } + + fn clear_bg(&mut self) -> io::Result<()> { + todo!() + } + + fn set_fg_color(&mut self, fg: Color) -> io::Result<()> { + todo!() + } + + fn set_bg_color(&mut self, bg: Color) -> io::Result<()> { + todo!() + } + + pub fn clear_screen(&mut self) -> io::Result<()> { + todo!() + } + + pub fn clear_to_line_end(&mut self) -> io::Result<()> { + todo!() + } + + pub fn clear_to_screen_end(&mut self) -> io::Result<()> { + todo!() + } + + pub fn move_up(&mut self, n: usize) -> io::Result<()> { + todo!() + } + + pub fn move_down(&mut self, n: usize) -> io::Result<()> { + todo!() + } + + pub fn move_left(&mut self, n: usize) -> io::Result<()> { + todo!() + } + + pub fn move_right(&mut self, n: usize) -> io::Result<()> { + todo!() + } + + pub fn move_to_first_column(&mut self) -> io::Result<()> { + todo!() + } + + pub fn move_cursor(&mut self, pos: Cursor) -> io::Result<()> { + todo!() + } + + pub fn set_cursor_mode(&mut self, mode: CursorMode) -> io::Result<()> { + todo!() + } + + pub fn write_char(&mut self, ch: char) -> io::Result<()> { + todo!() + } + + pub fn write_str(&mut self, s: &str) -> io::Result<()> { + todo!() + } + + pub fn write_styled(&mut self, + fg: Option, bg: Option, style: Style, text: &str) + -> io::Result<()> { + todo!() + } + + fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { + todo!() + } + + pub fn flush(&mut self) -> io::Result<()> { + todo!() + } + + fn write_data(&self, buf: &[u8]) -> (usize, io::Result<()>) { + todo!() + } +}