From 6b2805937de4df188430278955bf10db58794de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?joseLu=C3=ADs?= Date: Sat, 2 Jan 2021 19:45:15 +0100 Subject: [PATCH] rust: add new wrapper type over notcurses struct. Create new wrapping types that can safely encapsulate the mutable references, and implement Drop and automatic (de)referencing. - Notcurses - rename Notcurses* to NcNotcurses*. - rename NotcursesOptions to NcNotcursesOptions. - new Notcurses struct. - implement Drop, AsRef, AsMut, Deref & DerefMut. - override stop method to be no-op. - reimplement constructors and associated methods. - remove without_altscreen_with_banners constructor. - update examples and tests. - rustfmt. --- rust/examples/direct-cursor.rs | 10 +- rust/examples/direct-image-c.rs | 8 +- rust/examples/direct-image-rust.rs | 27 +++--- rust/examples/full-basics.rs | 6 +- rust/examples/full-input.rs | 14 ++- rust/examples/poc-cjkscroll.rs | 8 +- rust/examples/poc-menu.rs | 13 ++- rust/src/cells/reimplemented.rs | 8 +- rust/src/cells/test/methods.rs | 5 +- rust/src/direct/methods.rs | 11 ++- rust/src/fade.rs | 4 +- rust/src/lib.rs | 73 +++++++-------- rust/src/macros.rs | 21 ++++- rust/src/notcurses/helpers.rs | 8 +- rust/src/notcurses/methods.rs | 99 ++++++++++---------- rust/src/notcurses/mod.rs | 30 +++--- rust/src/notcurses/reimplemented.rs | 26 +++--- rust/src/notcurses/wrapper.rs | 140 ++++++++++++++++++++++++++++ rust/src/palette/methods.rs | 6 +- rust/src/plane/helpers.rs | 4 +- rust/src/plane/methods.rs | 112 +++++++++++----------- rust/src/stats.rs | 10 +- 22 files changed, 395 insertions(+), 248 deletions(-) create mode 100644 rust/src/notcurses/wrapper.rs diff --git a/rust/examples/direct-cursor.rs b/rust/examples/direct-cursor.rs index 17bc6f2e8..afd3dc62e 100644 --- a/rust/examples/direct-cursor.rs +++ b/rust/examples/direct-cursor.rs @@ -16,10 +16,8 @@ fn main() -> NcResult<()> { let rows = ncd.dim_y(); println!("terminal size (rows, cols): {}, {}", rows, cols); - let mut channels = NcChannelPair::combine( - NcChannel::with_rgb(0xAA2244), - NcChannel::with_rgb(0x112233), - ); + let mut channels = + NcChannelPair::combine(NcChannel::with_rgb(0xAA2244), NcChannel::with_rgb(0x112233)); ncd.putstr(channels, "The current coordinates are")?; for _n in 0..40 { @@ -41,7 +39,9 @@ fn main() -> NcResult<()> { ncd.putstr(channels, &format!(" ({},{})\n", cy, cx))?; sleep![1]; - let sentence = vec!["And", "now", "I", "will", "clear", "the", "screen", ".", ".", "."]; + let sentence = vec![ + "And", "now", "I", "will", "clear", "the", "screen", ".", ".", ".", + ]; for word in sentence { channels.set_fg_rgb(channels.fg_rgb().wrapping_sub(0x050505)); channels.set_bg_rgb(channels.bg_rgb().wrapping_add(0x090909)); diff --git a/rust/examples/direct-image-c.rs b/rust/examples/direct-image-c.rs index 7818213fd..43c896dec 100644 --- a/rust/examples/direct-image-c.rs +++ b/rust/examples/direct-image-c.rs @@ -4,8 +4,8 @@ //! //! NOTE: This example uses the C style with functions. -use libnotcurses_sys::*; use core::ptr::{null, null_mut}; +use libnotcurses_sys::*; fn main() { unsafe { @@ -29,8 +29,10 @@ fn render_image(ncd: &mut NcDirect, blit: NcBlitter) { NCSCALE_NONE, ) != 0 { - panic!("ERROR: ncdirect_render_image(). Make sure you \ - are running this example from the examples folder"); + panic!( + "ERROR: ncdirect_render_image(). Make sure you \ + are running this example from the examples folder" + ); } } } diff --git a/rust/examples/direct-image-rust.rs b/rust/examples/direct-image-rust.rs index 638bfe942..10d7ecc57 100644 --- a/rust/examples/direct-image-rust.rs +++ b/rust/examples/direct-image-rust.rs @@ -7,26 +7,23 @@ use libnotcurses_sys::*; fn main() -> NcResult<()> { - let ncd = NcDirect::new()?; + let ncd = NcDirect::new()?; - render_image(ncd, NCBLIT_1x1)?; - render_image(ncd, NCBLIT_2x1)?; - render_image(ncd, NCBLIT_BRAILLE)?; + render_image(ncd, NCBLIT_1x1)?; + render_image(ncd, NCBLIT_2x1)?; + render_image(ncd, NCBLIT_BRAILLE)?; - ncd.stop()?; - Ok(()) + ncd.stop()?; + Ok(()) } -fn render_image(ncd: &mut NcDirect, blit: NcBlitter) -> NcResult<()>{ - if let Err(nc_error) = ncd.render_image( - "image-16x16.png", - NCALIGN_CENTER, - blit, - NCSCALE_NONE, - ) { - return Err(NcError::with_msg(nc_error.int, +fn render_image(ncd: &mut NcDirect, blit: NcBlitter) -> NcResult<()> { + if let Err(nc_error) = ncd.render_image("image-16x16.png", NCALIGN_CENTER, blit, NCSCALE_NONE) { + return Err(NcError::with_msg( + nc_error.int, "ERROR: ncdirect_render_image(). Make sure you \ - are running this example from the examples folder")); + are running this example from the examples folder", + )); } Ok(()) } diff --git a/rust/examples/full-basics.rs b/rust/examples/full-basics.rs index c5f47fbf0..7906f6b97 100644 --- a/rust/examples/full-basics.rs +++ b/rust/examples/full-basics.rs @@ -1,17 +1,15 @@ use libnotcurses_sys::*; fn main() -> NcResult<()> { - let nc = Notcurses::new()?; + let mut nc = Notcurses::new()?; let stdplane = nc.stdplane()?; for ch in "Initializing cells...".chars() { let cell = NcCell::with_char7b(ch); stdplane.putc(&cell)?; - sleep![0, 40]; - nc.render()?; + rsleep![&mut nc, 0, 40]; } sleep![0, 900]; - nc.stop()?; Ok(()) } diff --git a/rust/examples/full-input.rs b/rust/examples/full-input.rs index 63cb5f08b..41e005a5c 100644 --- a/rust/examples/full-input.rs +++ b/rust/examples/full-input.rs @@ -6,11 +6,9 @@ use libnotcurses_sys::*; fn main() -> NcResult<()> { - let nc = Notcurses::with_flags( - NCOPTION_SUPPRESS_BANNERS - | NCOPTION_NO_WINCH_SIGHANDLER - | NCOPTION_NO_QUIT_SIGHANDLERS - )?; + let mut nc = Notcurses::with_flags( + NCOPTION_SUPPRESS_BANNERS | NCOPTION_NO_WINCH_SIGHANDLER | NCOPTION_NO_QUIT_SIGHANDLERS, + )?; // doesn't seem to be necessary: // let ready = unsafe { notcurses_inputready_fd(nc) }; @@ -21,13 +19,13 @@ fn main() -> NcResult<()> { let mut input = NcInput::new_empty(); loop { - let key = notcurses_getc_nblock(nc, &mut input); + let key = notcurses_getc_nblock(&mut nc, &mut input); if key as i32 != -1 { println!("'{0}' ({1:x})\n{2:?}", key, key as u32, input); } - rsleep![nc, 0, 10]; + rsleep![&mut nc, 0, 10]; match key { NCKEY_F01 => break, @@ -37,7 +35,7 @@ fn main() -> NcResult<()> { println!("\nExiting..."); - rsleep![nc, 1, 500]; + rsleep![&mut nc, 1, 500]; nc.stop()?; Ok(()) } diff --git a/rust/examples/poc-cjkscroll.rs b/rust/examples/poc-cjkscroll.rs index 059360b58..443be2ab7 100644 --- a/rust/examples/poc-cjkscroll.rs +++ b/rust/examples/poc-cjkscroll.rs @@ -3,8 +3,7 @@ use libnotcurses_sys::*; fn main() -> NcResult<()> { - - let nc = Notcurses::new()?; + let mut nc = Notcurses::new()?; let plane = nc.stdplane()?; plane.set_scrolling(true); @@ -14,9 +13,10 @@ fn main() -> NcResult<()> { plane.putchar(wc)?; wc = core::char::from_u32(wc as u32 + 1).expect("invalid char"); - if wc == '\u{9fa5}' { // 龣 + // 龣 + if wc == '\u{9fa5}' { wc = '\u{4e00}'; } - rsleep![nc, 0, 0, 50]; + rsleep![&mut nc, 0, 0, 30]; } } diff --git a/rust/examples/poc-menu.rs b/rust/examples/poc-menu.rs index 464e78995..91c943afe 100644 --- a/rust/examples/poc-menu.rs +++ b/rust/examples/poc-menu.rs @@ -3,7 +3,7 @@ use libnotcurses_sys::*; fn main() -> NcResult<()> { - let nc = Notcurses::new()?; + let mut nc = Notcurses::new()?; nc.mouse_enable()?; let mut demo_items = [ @@ -55,7 +55,7 @@ fn main() -> NcResult<()> { " -=+ menu poc. press q to exit +=-", )?; - run_menu(nc, menu_top)?; + run_menu(&mut nc, menu_top)?; stdplane.erase(); // is this needed? @@ -67,9 +67,8 @@ fn main() -> NcResult<()> { mopts.flags |= NCMENU_OPTION_BOTTOM; let menu_bottom = NcMenu::new(stdplane, mopts)?; - run_menu(nc, menu_bottom)?; + run_menu(&mut nc, menu_bottom)?; - nc.stop()?; Ok(()) } @@ -106,7 +105,7 @@ fn run_menu(nc: &mut Notcurses, menu: &mut NcMenu) -> NcResult<()> { menu.destroy()?; selplane.destroy()?; return Ok(()); - }, + } NCKEY_ENTER => { if let Some(selection) = menu.selected(Some(&mut ni)) { match selection.as_ref() { @@ -115,11 +114,11 @@ fn run_menu(nc: &mut Notcurses, menu: &mut NcMenu) -> NcResult<()> { selplane.destroy()?; return Ok(()); } - _ => () + _ => (), } } } - _ => () + _ => (), } } diff --git a/rust/src/cells/reimplemented.rs b/rust/src/cells/reimplemented.rs index 2a56aacd5..064fa9081 100644 --- a/rust/src/cells/reimplemented.rs +++ b/rust/src/cells/reimplemented.rs @@ -3,10 +3,10 @@ use libc::strcmp; use crate::{ - cstring, cell_release, NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcEgc, NcIntResult, - NcPaletteIndex, NcPlane, NcRgb, NcStyleMask, NCCELL_ALPHA_OPAQUE, NCCELL_BGDEFAULT_MASK, - NCCELL_BG_PALETTE, NCCELL_FGDEFAULT_MASK, NCCELL_FG_PALETTE, NCCELL_NOBACKGROUND_MASK, - NCCELL_WIDEASIAN_MASK, NCRESULT_ERR, NCRESULT_OK, NCSTYLE_MASK, + cell_release, cstring, NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcEgc, + NcIntResult, NcPaletteIndex, NcPlane, NcRgb, NcStyleMask, NCCELL_ALPHA_OPAQUE, + NCCELL_BGDEFAULT_MASK, NCCELL_BG_PALETTE, NCCELL_FGDEFAULT_MASK, NCCELL_FG_PALETTE, + NCCELL_NOBACKGROUND_MASK, NCCELL_WIDEASIAN_MASK, NCRESULT_ERR, NCRESULT_OK, NCSTYLE_MASK, }; // Alpha ----------------------------------------------------------------------- diff --git a/rust/src/cells/test/methods.rs b/rust/src/cells/test/methods.rs index 71444258b..07b38599e 100644 --- a/rust/src/cells/test/methods.rs +++ b/rust/src/cells/test/methods.rs @@ -10,9 +10,8 @@ fn constructors() -> crate::NcResult<()> { let _c1 = NcCell::new(); let _c2 = NcCell::with_char7b('C'); - let nc = Notcurses::new()?; - let plane = NcPlane::new(nc, 0, 0, 10, 10)?; + let mut nc = Notcurses::new()?; + let plane = NcPlane::new(&mut nc, 0, 0, 10, 10)?; let _c3 = NcCell::with_char('௵', plane); - nc.stop()?; Ok(()) } diff --git a/rust/src/direct/methods.rs b/rust/src/direct/methods.rs index 42b0aa887..60734b0bb 100644 --- a/rust/src/direct/methods.rs +++ b/rust/src/direct/methods.rs @@ -164,7 +164,10 @@ impl NcDirect { pub fn palette_size(&self) -> NcResult { let res = unsafe { crate::ncdirect_palette_size(self) }; if res == 1 { - return Err(NcError::with_msg(1, "No color support ← NcDirect.palette_size()")); + return Err(NcError::with_msg( + 1, + "No color support ← NcDirect.palette_size()", + )); } Ok(res) } @@ -550,8 +553,10 @@ impl NcDirect { ctlword, ) }, - &format!("NcDirect.box({:0X}, {:0X}, {:0X}, {:0X}, {:?}, {}, {}, {})", - ul, ur, ll, lr, wchars, y_len, x_len, ctlword) + &format!( + "NcDirect.box({:0X}, {:0X}, {:0X}, {:0X}, {:?}, {}, {}, {})", + ul, ur, ll, lr, wchars, y_len, x_len, ctlword + ) ] } diff --git a/rust/src/fade.rs b/rust/src/fade.rs index c79613425..f6c739562 100644 --- a/rust/src/fade.rs +++ b/rust/src/fade.rs @@ -11,7 +11,7 @@ use std::ffi::c_void; -use crate::{NcIntResult, NcPlane, NcTime, Notcurses}; +use crate::{NcIntResult, NcNotcurses, NcPlane, NcTime}; /// Called for each fade iteration on the NcPlane. /// @@ -20,7 +20,7 @@ use crate::{NcIntResult, NcPlane, NcTime, Notcurses}; /// /// The recommended absolute display time target is passed in 'tspec'. pub type NcFadeCb = Option< - unsafe extern "C" fn(*mut Notcurses, *mut NcPlane, *const NcTime, *mut c_void) -> NcIntResult, + unsafe extern "C" fn(*mut NcNotcurses, *mut NcPlane, *const NcTime, *mut c_void) -> NcIntResult, >; /// Context for a palette fade operation diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 35fd5c0ec..665036ae5 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,50 +1,52 @@ -//! `libnotcurses-sys` is a *close to the metal* Rust wrapper for the [notcurses +//! `libnotcurses-sys` is a Rust wrapper for the [notcurses //! C library](https://www.github.com/dankamongmen/notcurses/) //! -//! The bindings are still incomplete, and a work in progress. +//! *This is a work in progress.* //! -//! # Ways of using this library +//! # How to use this library +//! +//! Since this library is built with several layers of zero-overhead +//! abstractions over the FFI functions, there are multiple ways to use it. +//! +//! But basically there are two ways: +//! +//! ## 1. The Rust way +//! +//! Use the safely wrapped types, their methods and constructors: //! -//! The *rusty* way is to use the provided methods and constructors: //! ```rust //! use libnotcurses_sys::*; //! //! fn main() -> NcResult<()> { -//! let nc = Notcurses::without_altscreen()?; +//! let mut nc = Notcurses::with_flags(NCOPTION_NO_ALTERNATE_SCREEN)?; //! let plane = nc.stdplane()?; //! plane.putstr("hello world")?; //! nc.render()?; -//! nc.stop()?; //! Ok(()) //! } //! ``` +//! Specifically, and for example: //! -//! You can also use the C API functions directly over the constructed types. +//! [`Notcurses`] is the safe wrapper over [`NcNotcurses`], which is the +//! `&mut` reference over the raw `*mut` pointer received from FFI. //! -//! Note that some of the functions will be unsafe. And you may also need -//! to (de)reference mutable pointers. -//! This is mainly due to the interaction between the manually reimplemented -//! static inline functions that uses (mutable) references, and the C API -//! functions automatically wrapped by bindgen that uses (mutable) raw pointers. +//! Notcurses implements the [Drop], [AsRef], [AsMut], [Deref][std::ops::Deref] +//! & [DerefMut][std::ops::DerefMut] traits. //! -//! There are plans to manually wrap all the C API functions, in order to -//! achieve better ergonomics and consistent syntax. -//! ```rust -//! use libnotcurses_sys::*; +//! Most methods are directly implemented for NcNotcurses, +//! and automatically available also from Notcurses. //! -//! fn main() { -//! let options = NotcursesOptions::with_flags(NCOPTION_NO_ALTERNATE_SCREEN); -//! unsafe { -//! let nc = notcurses_init(&options, core::ptr::null_mut()); -//! let plane = notcurses_stdplane(nc); -//! ncplane_putstr(&mut *plane, "hello world"); -//! notcurses_render(nc); -//! notcurses_stop(nc); -//! } -//! } -//! ``` +//! The destructor ([notcurses_stop()]) is called automatically at the end +//! of its scope, so you don't ever have to call it by hand. +//! +//! The Rust style methods manage errors by means of returning an +//! [`NcResult`]``, for painless handling. +//! +//! ## 2. The C way +//! +//! You can also use the C API functions directly in a very similar way +//! as the underlying C library is used. //! -//! You can also use it even more closely to the C API if you wish: //! ```rust //! use core::ptr::{null, null_mut}; //! use libnotcurses_sys::*; @@ -60,6 +62,7 @@ //! margin_l: 0, //! flags: NCOPTION_NO_ALTERNATE_SCREEN, //! }; +//! // NOTE: there's missing manual checking of return values for errors. //! unsafe { //! let nc = notcurses_init(&options, null_mut()); //! let plane = notcurses_stdplane(nc); @@ -69,18 +72,10 @@ //! } //! //! ``` -//! ## About this library -//! -//! 1. There are no Drop trait implementations, therefore you must manually stop -//! each context before it goes out of scope ([Notcurses], [NcDirect]), and -//! should manually destroy [NcPlane]s, [NcMenu]s… when no longer needed. -//! -//! 2. The C style functions handle errors by the means of returning an i32 value -//! aliased to [NcIntResult]. But the Rust style methods handle errors more -//! idiomatically using [NcResult] and [NcError]. -//! +//! It requires the use of unsafe. //! -//! [Macros][#macros] are +//! The C style functions handle errors by the means of returning an i32 value +//! aliased to [NcIntResult]. //! //! ## The `notcurses` C API docs //! diff --git a/rust/src/macros.rs b/rust/src/macros.rs index b65ee0fd0..1c98116b0 100644 --- a/rust/src/macros.rs +++ b/rust/src/macros.rs @@ -5,7 +5,7 @@ #[allow(unused_imports)] // enjoy briefer doc comments -use crate::{NcDirect, NcError, NcResult, Notcurses, NCRESULT_ERR, NCRESULT_OK}; +use crate::{NcDirect, NcError, NcNotcurses, NcResult, NCRESULT_ERR, NCRESULT_OK}; // Sleep, Render & Flush Macros ------------------------------------------------ @@ -32,9 +32,9 @@ macro_rules! sleep { }; } -/// Notcurses.[render][Notcurses#method.render]\(`nc`\)? plus [sleep]!(`sleep_args`). +/// NcNotcurses.[render][NcNotcurses#method.render]\(`nc`\)? plus [sleep]!(`sleep_args`). /// -/// Renders the `$nc` [Notcurses] object and, if there's no error, +/// Renders the `$nc` [NcNotcurses] object and, if there's no error, /// calls the sleep macro with the rest of the arguments. /// /// Returns [NcResult]. @@ -42,7 +42,7 @@ macro_rules! sleep { macro_rules! rsleep { ($nc:expr, $( $sleep_args:expr),+ ) => { // Rust style, with methods & NcResult - Notcurses::render($nc)?; + NcNotcurses::render($nc)?; sleep![$( $sleep_args ),+]; }; ($nc:expr, $( $sleep_args:expr),+ ,) => { @@ -91,7 +91,7 @@ macro_rules! cstring_mut { macro_rules! rstring { ($s:expr) => { unsafe { std::ffi::CStr::from_ptr($s).to_str().unwrap() } - // possible alternative + // possible alternative: // unsafe { std::ffi::CStr::from_ptr($s).to_string_lossy() } }; } @@ -203,3 +203,14 @@ macro_rules! error_str { error_str![$str, ""]; }; } + +/// Returns an NcResult from an NcResult. +#[macro_export] +macro_rules! raw_wrap { + ($res:expr) => { + match $res { + Ok(raw) => return Ok(Self { raw }), + Err(e) => return Err(e), + } + }; +} diff --git a/rust/src/notcurses/helpers.rs b/rust/src/notcurses/helpers.rs index 2b93cf922..9164c700c 100644 --- a/rust/src/notcurses/helpers.rs +++ b/rust/src/notcurses/helpers.rs @@ -1,10 +1,10 @@ -use crate::{notcurses_init, Notcurses, NotcursesOptions, NCOPTION_SUPPRESS_BANNERS}; +use crate::{notcurses_init, NcNotcurses, NcNotcursesOptions, NCOPTION_SUPPRESS_BANNERS}; -/// Helper function for initializing Notcurses on C style tests. +/// Helper function for initializing NcNotcurses on C style tests. #[allow(dead_code)] -pub(crate) unsafe fn notcurses_init_test<'a>() -> &'a mut Notcurses { +pub(crate) unsafe fn notcurses_init_test<'a>() -> &'a mut NcNotcurses { &mut *notcurses_init( - &NotcursesOptions::with_flags(NCOPTION_SUPPRESS_BANNERS), + &NcNotcursesOptions::with_flags(NCOPTION_SUPPRESS_BANNERS), core::ptr::null_mut(), ) } diff --git a/rust/src/notcurses/methods.rs b/rust/src/notcurses/methods.rs index c589cae3c..05c734f28 100644 --- a/rust/src/notcurses/methods.rs +++ b/rust/src/notcurses/methods.rs @@ -1,22 +1,22 @@ -//! `Notcurses*` methods and associated functions. +//! `NcNotcurses*` methods and associated functions. use core::ptr::{null, null_mut}; use crate::{ cstring, error, error_ref_mut, notcurses_init, rstring, NcAlign, NcBlitter, NcChannelPair, - NcDimension, NcEgc, NcError, NcFile, NcInput, NcLogLevel, NcPlane, NcResult, NcScale, - NcSignalSet, NcStats, NcStyleMask, NcTime, Notcurses, NotcursesOptions, + NcDimension, NcEgc, NcError, NcFile, NcInput, NcLogLevel, NcNotcurses, NcNotcursesOptions, + NcPlane, NcResult, NcScale, NcSignalSet, NcStats, NcStyleMask, NcTime, NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS, NCRESULT_ERR, }; -/// # `NotcursesOptions` Constructors -impl NotcursesOptions { - /// New NotcursesOptions. +/// # `NcNotcursesOptions` Constructors +impl NcNotcursesOptions { + /// New NcNotcursesOptions. pub const fn new() -> Self { Self::with_all_options(0, 0, 0, 0, 0, 0) } - /// New NotcursesOptions, with margins. + /// New NcNotcursesOptions, with margins. pub const fn with_margins( top: NcDimension, right: NcDimension, @@ -26,12 +26,12 @@ impl NotcursesOptions { Self::with_all_options(0, top, right, bottom, left, 0) } - /// New NotcursesOptions, with flags. + /// New NcNotcursesOptions, with flags. pub const fn with_flags(flags: u64) -> Self { Self::with_all_options(0, 0, 0, 0, 0, flags) } - /// New NotcursesOptions, with all the options. + /// New NcNotcursesOptions, with all the options. /// /// ## Arguments /// @@ -83,51 +83,46 @@ impl NotcursesOptions { } } -/// # `Notcurses` Constructors -impl Notcurses { - /// New Notcurses (without banners). - pub fn new<'a>() -> NcResult<&'a mut Notcurses> { +/// # `NcNotcurses` Constructors +impl NcNotcurses { + /// New NcNotcurses (without banners). + pub fn new<'a>() -> NcResult<&'a mut NcNotcurses> { Self::with_flags(NCOPTION_SUPPRESS_BANNERS) } - /// New Notcurses, with banners. + /// New NcNotcurses, with banners. /// /// This is the default in the C library. - pub fn with_banners<'a>() -> NcResult<&'a mut Notcurses> { + pub fn with_banners<'a>() -> NcResult<&'a mut NcNotcurses> { Self::with_flags(0) } - /// New Notcurses, without an alternate screen (nor banners). - pub fn without_altscreen<'a>() -> NcResult<&'a mut Notcurses> { - Self::with_flags(NCOPTION_NO_ALTERNATE_SCREEN) - } - - /// New Notcurses, without an alternate screen, with banners. - pub fn without_altscreen_nor_banners<'a>() -> NcResult<&'a mut Notcurses> { + /// New NcNotcurses, without an alternate screen (nor banners). + pub fn without_altscreen<'a>() -> NcResult<&'a mut NcNotcurses> { Self::with_flags(NCOPTION_NO_ALTERNATE_SCREEN | NCOPTION_SUPPRESS_BANNERS) } - /// New Notcurses, expects `NCOPTION_*` flags. - pub fn with_flags<'a>(flags: u64) -> NcResult<&'a mut Notcurses> { - Self::with_options(NotcursesOptions::with_flags(flags)) + /// New NcNotcurses, expects `NCOPTION_*` flags. + pub fn with_flags<'a>(flags: u64) -> NcResult<&'a mut NcNotcurses> { + Self::with_options(NcNotcursesOptions::with_flags(flags)) } - /// New Notcurses, expects [NotcursesOptions]. - pub fn with_options<'a>(options: NotcursesOptions) -> NcResult<&'a mut Notcurses> { + /// New NcNotcurses, expects [NcNotcursesOptions]. + pub fn with_options<'a>(options: NcNotcursesOptions) -> NcResult<&'a mut NcNotcurses> { let res = unsafe { notcurses_init(&options, null_mut()) }; - error_ref_mut![res, "Notcurses.with_options()"] + error_ref_mut![res, "NcNotcurses.with_options()"] } - /// New Notcurses, expects [NcLogLevel] and flags. - pub fn with_debug<'a>(loglevel: NcLogLevel, flags: u64) -> NcResult<&'a mut Notcurses> { - Self::with_options(NotcursesOptions::with_all_options( + /// New NcNotcurses, expects [NcLogLevel] and flags. + pub fn with_debug<'a>(loglevel: NcLogLevel, flags: u64) -> NcResult<&'a mut NcNotcurses> { + Self::with_options(NcNotcursesOptions::with_all_options( loglevel, 0, 0, 0, 0, flags, )) } } -/// # `Notcurses` methods -impl Notcurses { +/// # `NcNotcurses` methods +impl NcNotcurses { /// Returns the offset into `availcols` at which `cols` ought be output given /// the requirements of `align`. /// @@ -135,6 +130,8 @@ impl Notcurses { /// [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED] or invalid [NcAlign]. /// /// *C style function: [notcurses_align()][crate::notcurses_align].* + // + // TODO: handle error rightfully. pub fn align(availcols: NcDimension, align: NcAlign, cols: NcDimension) -> NcResult<()> { error![crate::notcurses_align(availcols, align, cols)] } @@ -256,7 +253,7 @@ impl Notcurses { error![unsafe { crate::notcurses_cursor_enable(self, y as i32, x as i32) }] } - /// Dumps Notcurses state to the supplied `debugfp`. + /// Dumps NcNotcurses state to the supplied `debugfp`. /// /// Output is freeform, and subject to change. It includes geometry of all /// planes, from all piles. @@ -356,7 +353,7 @@ impl Notcurses { } else { error![ -1, - &format!("Notcurses.getc_blocking({:?})", input_txt), + &format!("NcNotcurses.getc_blocking({:?})", input_txt), res ] } @@ -365,7 +362,7 @@ impl Notcurses { /// Gets a file descriptor suitable for input event poll()ing. /// /// When this descriptor becomes available, you can call - /// [getc_nblock()][Notcurses#method.getc_nblock], and input ought be ready. + /// [getc_nblock()][NcNotcurses#method.getc_nblock], and input ought be ready. /// /// This file descriptor is not necessarily the file descriptor associated /// with stdin (but it might be!). @@ -386,13 +383,13 @@ impl Notcurses { ] } - /// Lexes a margin argument according to the standard Notcurses definition. + /// Lexes a margin argument according to the standard NcNotcurses definition. /// /// There can be either a single number, which will define all margins equally, /// or there can be four numbers separated by commas. /// /// *C style function: [notcurses_lex_margins()][crate::notcurses_lex_margins].* - pub fn lex_margins(op: &str, options: &mut NotcursesOptions) -> NcResult<()> { + pub fn lex_margins(op: &str, options: &mut NcNotcursesOptions) -> NcResult<()> { error![unsafe { crate::notcurses_lex_margins(cstring![op], options) }] } @@ -435,13 +432,13 @@ impl Notcurses { /// Enable the mouse in "button-event tracking" mode with focus detection /// and UTF8-style extended coordinates. /// - /// On success, mouse events will be published to [getc()][Notcurses#method.getc]. + /// On success, mouse events will be published to [getc()][NcNotcurses#method.getc]. /// /// *C style function: [notcurses_mouse_enable()][crate::notcurses_mouse_enable].* pub fn mouse_enable(&mut self) -> NcResult<()> { error![ unsafe { crate::notcurses_mouse_enable(self) }, - "Notcurses.mouse_enable()" + "NcNotcurses.mouse_enable()" ] } @@ -458,7 +455,7 @@ impl Notcurses { /// Refreshes the physical screen to match what was last rendered (i.e., /// without reflecting any changes since the last call to - /// [render][crate::Notcurses#method.render]). + /// [render][crate::NcNotcurses#method.render]). /// /// This is primarily useful if the screen is externally corrupted, or if an /// [NCKEY_RESIZE][crate::NCKEY_RESIZE] event has been read and you're not @@ -481,12 +478,12 @@ impl Notcurses { pub fn render(&mut self) -> NcResult<()> { error![ unsafe { crate::notcurses_render(self) }, - "Notcurses.render()" + "NcNotcurses.render()" ] } /// Performs the rendering and rasterization portion of - /// [render][Notcurses#method.render] but do not write the resulting buffer + /// [render][NcNotcurses#method.render] but do not write the resulting buffer /// out to the terminal. /// /// Using this function, the user can control the writeout process, @@ -505,7 +502,7 @@ impl Notcurses { /// Writes the last rendered frame, in its entirety, to 'fp'. /// - /// If [render()][Notcurses#method.render] has not yet been called, + /// If [render()][NcNotcurses#method.render] has not yet been called, /// nothing will be written. /// /// *C style function: [notcurses_render_to_file()][crate::notcurses_render_to_file].* @@ -513,7 +510,7 @@ impl Notcurses { error![unsafe { crate::notcurses_render_to_file(self, fp.as_nc_ptr()) }] } - /// Acquires an atomic snapshot of the Notcurses object's stats. + /// Acquires an atomic snapshot of the NcNotcurses object's stats. /// /// *C style function: [notcurses_stats()][crate::notcurses_stats].* pub fn stats(&mut self, stats: &mut NcStats) { @@ -525,7 +522,7 @@ impl Notcurses { /// Allocates an ncstats object. /// /// Use this rather than allocating your own, since future versions of - /// Notcurses might enlarge this structure. + /// NcNotcurses might enlarge this structure. /// /// *C style function: [notcurses_stats_alloc()][crate::notcurses_stats_alloc].* pub fn stats_alloc<'a>(&'a mut self) -> &'a mut NcStats { @@ -554,7 +551,7 @@ impl Notcurses { // crate::notcurses_stddim_yx(self, y, x) // } - // /// [stdplane_const()][Notcurses#method.stdplane_const], plus free + // /// [stdplane_const()][NcNotcurses#method.stdplane_const], plus free // /// bonus dimensions written to non-NULL y/x! // /// // /// *C style function: [notcurses_stddim_yx()][crate::notcurses_stddim_yx].* @@ -576,7 +573,7 @@ impl Notcurses { pub fn stdplane<'a>(&mut self) -> NcResult<&'a mut NcPlane> { error_ref_mut![ unsafe { crate::notcurses_stdplane(self) }, - "Notcurses.stdplane()" + "NcNotcurses.stdplane()" ] } @@ -590,7 +587,7 @@ impl Notcurses { unsafe { &*crate::notcurses_stdplane_const(self) } } - /// Destroys the Notcurses context. + /// Destroys the NcNotcurses context. /// /// *C style function: [notcurses_stop()][crate::notcurses_stop].* pub fn stop(&mut self) -> NcResult<()> { @@ -637,14 +634,14 @@ impl Notcurses { unsafe { &mut *crate::notcurses_top(self) } } - /// Returns a human-readable string describing the running Notcurses version. + /// Returns a human-readable string describing the running notcurses version. /// /// *C style function: [notcurses_version()][crate::notcurses_version].* pub fn version() -> String { rstring![crate::notcurses_version()].to_string() } - /// Returns the running Notcurses version components + /// Returns the running NcNotcurses version components /// (major, minor, patch, tweak). /// /// *C style function: [notcurses_version_components()][crate::notcurses_version_components].* diff --git a/rust/src/notcurses/mod.rs b/rust/src/notcurses/mod.rs index bbf8f1323..cda075d1d 100644 --- a/rust/src/notcurses/mod.rs +++ b/rust/src/notcurses/mod.rs @@ -1,4 +1,4 @@ -//! `Notcurses` +//! `NcNotcurses` // functions already exported by bindgen : 42 // ------------------------------------------ @@ -67,20 +67,22 @@ mod test; mod helpers; mod methods; mod reimplemented; +mod wrapper; #[allow(unused_imports)] pub(crate) use helpers::*; pub use reimplemented::*; +pub use wrapper::*; -/// The main struct of the TUI library (full mode) -/// -/// Notcurses builds atop the terminfo abstraction layer to +/// NcNotcurses builds atop the terminfo abstraction layer to /// provide reasonably portable vivid character displays. /// -pub type Notcurses = crate::bindings::ffi::notcurses; +/// This is the internal type safely wrapped by [Notcurses]. +/// +pub type NcNotcurses = crate::bindings::ffi::notcurses; -/// Options struct for [`Notcurses`] -pub type NotcursesOptions = crate::bindings::ffi::notcurses_options; +/// Options struct for [`NcNotcurses`] +pub type NcNotcursesOptions = crate::bindings::ffi::notcurses_options; /// Do not call setlocale() /// @@ -96,17 +98,17 @@ pub const NCOPTION_INHIBIT_SETLOCALE: u64 = crate::bindings::ffi::NCOPTION_INHIB /// Do not enter alternate mode. /// -/// If smcup/rmcup capabilities are indicated, Notcurses defaults to making use +/// If smcup/rmcup capabilities are indicated, NcNotcurses defaults to making use /// of the "alternate screen". This flag inhibits use of smcup/rmcup. pub const NCOPTION_NO_ALTERNATE_SCREEN: u64 = crate::bindings::ffi::NCOPTION_NO_ALTERNATE_SCREEN as u64; /// Do not modify the font. /// -/// Notcurses might attempt to change the font slightly, to support certain +/// NcNotcurses might attempt to change the font slightly, to support certain /// glyphs (especially on the Linux console). If this is set, no such /// modifications will be made. Note that font changes will not affect anything -/// but the virtual console/terminal in which Notcurses is running. +/// but the virtual console/terminal in which NcNotcurses is running. pub const NCOPTION_NO_FONT_CHANGES: u64 = crate::bindings::ffi::NCOPTION_NO_FONT_CHANGES as u64; /// Do not handle SIG{ING, SEGV, ABRT, QUIT} @@ -127,7 +129,7 @@ pub const NCOPTION_NO_WINCH_SIGHANDLER: u64 = /// Do not print banners /// -/// Notcurses typically prints version info in notcurses_init() and performance +/// NcNotcurses typically prints version info in notcurses_init() and performance /// info in notcurses_stop(). This inhibits that output. pub const NCOPTION_SUPPRESS_BANNERS: u64 = crate::bindings::ffi::NCOPTION_SUPPRESS_BANNERS as u64; @@ -141,11 +143,11 @@ pub const NCOPTION_VERIFY_SIXEL: u64 = crate::bindings::ffi::NCOPTION_VERIFY_SIX // NcLogLevel ------------------------------------------------------------------ -/// Log level for [`NotcursesOptions`] +/// Log level for [`NcNotcursesOptions`] /// -/// These log levels consciously map cleanly to those of libav; Notcurses itself +/// These log levels consciously map cleanly to those of libav; NcNotcurses itself /// does not use this full granularity. The log level does not affect the opening -/// and closing banners, which can be disabled via the `NotcursesOptions` +/// and closing banners, which can be disabled via the `NcNotcursesOptions` /// `NCOPTION_SUPPRESS_BANNERS`. /// Note that if stderr is connected to the same terminal on which we're /// rendering, any kind of logging will disrupt the output. diff --git a/rust/src/notcurses/reimplemented.rs b/rust/src/notcurses/reimplemented.rs index ef0776302..6054a8a1d 100644 --- a/rust/src/notcurses/reimplemented.rs +++ b/rust/src/notcurses/reimplemented.rs @@ -3,8 +3,8 @@ use core::ptr::{null, null_mut}; use crate::{ - NcAlign, NcDimension, NcError, NcInput, NcOffset, NcPlane, NcResult, NcSignalSet, NcTime, - Notcurses, NCALIGN_CENTER, NCALIGN_LEFT, NCALIGN_RIGHT, NCRESULT_ERR, NCRESULT_MAX, + NcAlign, NcDimension, NcError, NcInput, NcNotcurses, NcOffset, NcPlane, NcResult, NcSignalSet, + NcTime, NCALIGN_CENTER, NCALIGN_LEFT, NCALIGN_RIGHT, NCRESULT_ERR, NCRESULT_MAX, }; /// Returns the offset into `availcols` at which `cols` ought be output given @@ -13,7 +13,7 @@ use crate::{ /// Returns `-`[`NCRESULT_MAX`] if [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED] /// or invalid [NcAlign]. /// -/// *Method: Notcurses.[align()][Notcurses#method.align].* +/// *Method: NcNotcurses.[align()][NcNotcurses#method.align].* #[inline] pub fn notcurses_align(availcols: NcDimension, align: NcAlign, cols: NcDimension) -> NcOffset { if align == NCALIGN_LEFT { @@ -34,11 +34,11 @@ pub fn notcurses_align(availcols: NcDimension, align: NcAlign, cols: NcDimension /// /// If no event is ready, returns 0. /// -/// *Method: Notcurses.[getc_nblock()][Notcurses#method.getc_nblock].* +/// *Method: NcNotcurses.[getc_nblock()][NcNotcurses#method.getc_nblock].* // // TODO: use from_u32 & return Option. #[inline] -pub fn notcurses_getc_nblock(nc: &mut Notcurses, input: &mut NcInput) -> char { +pub fn notcurses_getc_nblock(nc: &mut NcNotcurses, input: &mut NcInput) -> char { unsafe { let mut sigmask = NcSignalSet::new(); sigmask.fillset(); @@ -56,9 +56,9 @@ pub fn notcurses_getc_nblock(nc: &mut Notcurses, input: &mut NcInput) -> char { /// /// In case of an invalid read (including on EOF) *-1 as char* is returned. /// -/// *Method: Notcurses.[getc_blocking()][Notcurses#method.getc_blocking].* +/// *Method: NcNotcurses.[getc_blocking()][NcNotcurses#method.getc_blocking].* #[inline] -pub fn notcurses_getc_blocking(nc: &mut Notcurses, input: Option<&mut NcInput>) -> char { +pub fn notcurses_getc_blocking(nc: &mut NcNotcurses, input: Option<&mut NcInput>) -> char { let input_ptr; if let Some(i) = input { input_ptr = i as *mut _; @@ -75,10 +75,10 @@ pub fn notcurses_getc_blocking(nc: &mut Notcurses, input: Option<&mut NcInput>) /// [notcurses_stdplane()][crate::notcurses_stdplane], plus free bonus /// dimensions written to non-NULL y/x! /// -/// *Method: Notcurses.[getc_stddim_yx()][Notcurses#method.stddim_yx].* +/// *Method: NcNotcurses.[getc_stddim_yx()][NcNotcurses#method.stddim_yx].* #[inline] pub fn notcurses_stddim_yx<'a>( - nc: &'a mut Notcurses, + nc: &'a mut NcNotcurses, y: &mut NcDimension, x: &mut NcDimension, ) -> NcResult<&'a mut NcPlane> { @@ -95,10 +95,10 @@ pub fn notcurses_stddim_yx<'a>( /// [notcurses_stdplane_const()][crate::notcurses_stdplane_const], plus free /// bonus dimensions written to non-NULL y/x! /// -/// *Method: Notcurses.[getc_stddim_yx_const()][Notcurses#method.stddim_yx_const].* +/// *Method: NcNotcurses.[getc_stddim_yx_const()][NcNotcurses#method.stddim_yx_const].* #[inline] pub fn notcurses_stddim_yx_const<'a>( - nc: &'a Notcurses, + nc: &'a NcNotcurses, y: &mut NcDimension, x: &mut NcDimension, ) -> NcResult<&'a NcPlane> { @@ -114,9 +114,9 @@ pub fn notcurses_stddim_yx_const<'a>( /// Returns our current idea of the terminal dimensions in rows and cols. /// -/// *Method: Notcurses.[getc_term_yx()][Notcurses#method.term_yx].* +/// *Method: NcNotcurses.[getc_term_yx()][NcNotcurses#method.term_yx].* #[inline] -pub fn notcurses_term_dim_yx(nc: &Notcurses) -> (NcDimension, NcDimension) { +pub fn notcurses_term_dim_yx(nc: &NcNotcurses) -> (NcDimension, NcDimension) { let (mut y, mut x) = (0, 0); unsafe { crate::ncplane_dim_yx(crate::notcurses_stdplane_const(nc), &mut y, &mut x); diff --git a/rust/src/notcurses/wrapper.rs b/rust/src/notcurses/wrapper.rs new file mode 100644 index 000000000..178862d3d --- /dev/null +++ b/rust/src/notcurses/wrapper.rs @@ -0,0 +1,140 @@ +//! `Notcurses` wrapper struct and traits implementations. + +use std::ops::{Deref, DerefMut}; + +use crate::{ + raw_wrap, NcAlign, NcBlitter, NcDimension, NcLogLevel, NcNotcurses, NcNotcursesOptions, + NcResult, NcScale, +}; + +/// The main struct of the TUI library (full mode). +/// +/// Safely wraps an [NcNotcurses], +/// and implements Drop, AsRef, AsMut, Deref & DerefMut around it. +pub struct Notcurses<'a> { + raw: &'a mut NcNotcurses, +} + +impl<'a> AsRef for Notcurses<'a> { + fn as_ref(&self) -> &NcNotcurses { + self.raw + } +} + +impl<'a> AsMut for Notcurses<'a> { + fn as_mut(&mut self) -> &mut NcNotcurses { + self.raw + } +} + +impl<'a> Deref for Notcurses<'a> { + type Target = NcNotcurses; + + fn deref(&self) -> &Self::Target { + self.as_ref() + } +} + +impl<'a> DerefMut for Notcurses<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_mut() + } +} + +impl<'a> Drop for Notcurses<'a> { + /// Destroys the Notcurses context. + fn drop(&mut self) { + let _ = self.raw.stop(); + } +} + +/// # Constructors and methods overriden from NcNotcurses +impl<'a> Notcurses<'a> { + // wrap constructors + + /// New Notcurses (without banners). + pub fn new() -> NcResult { + raw_wrap![NcNotcurses::new()] + } + + /// New Notcurses, without banners. + pub fn with_banners() -> NcResult { + raw_wrap![NcNotcurses::with_banners()] + } + + /// New Notcurses, without an alternate screen (nor banners). + pub fn without_altscreen() -> NcResult { + raw_wrap![NcNotcurses::without_altscreen()] + } + + /// New Notcurses, expects `NCOPTION_*` flags. + pub fn with_flags(flags: u64) -> NcResult { + raw_wrap![NcNotcurses::with_flags(flags)] + } + + /// New Notcurses, expects [NcNotcursesOptions]. + pub fn with_options(options: NcNotcursesOptions) -> NcResult { + raw_wrap![NcNotcurses::with_options(options)] + } + + /// New Notcurses, expects [NcLogLevel] and flags. + pub fn with_debug(loglevel: NcLogLevel, flags: u64) -> NcResult { + raw_wrap![NcNotcurses::with_debug(loglevel, flags)] + } + + // disable destructor + + /// Since Notcurses already implements [Drop](#impl-Drop), + /// this function is made no-op. + pub fn stop(&mut self) -> NcResult<()> { + Ok(()) + } + + // wrap associated functions + + /// Returns the offset into `availcols` at which `cols` ought be output given + /// the requirements of `align`. + pub fn align(availcols: NcDimension, align: NcAlign, cols: NcDimension) -> NcResult<()> { + NcNotcurses::align(availcols, align, cols) + } + + /// Gets the name of an [NcBlitter] blitter. + pub fn str_blitter(blitter: NcBlitter) -> String { + NcNotcurses::str_blitter(blitter) + } + + /// Gets the name of an [NcScale] scaling mode. + pub fn str_scalemode(scalemode: NcScale) -> String { + NcNotcurses::str_scalemode(scalemode) + } + + /// Returns an [NcBlitter] from a string representation. + pub fn lex_blitter(op: &str) -> NcResult { + NcNotcurses::lex_blitter(op) + } + + /// Lexes a margin argument according to the standard NcNotcurses definition. + /// + /// There can be either a single number, which will define all margins equally, + /// or there can be four numbers separated by commas. + /// + pub fn lex_margins(op: &str, options: &mut NcNotcursesOptions) -> NcResult<()> { + NcNotcurses::lex_margins(op, options) + } + + /// Returns an [NcScale] from a string representation. + pub fn lex_scalemode(op: &str) -> NcResult { + NcNotcurses::lex_scalemode(op) + } + + /// Returns a human-readable string describing the running Notcurses version. + pub fn version() -> String { + NcNotcurses::version() + } + + /// Returns the running NcNotcurses version components + /// (major, minor, patch, tweak). + pub fn version_components() -> (u32, u32, u32, u32) { + NcNotcurses::version_components() + } +} diff --git a/rust/src/palette/methods.rs b/rust/src/palette/methods.rs index 4c4b94337..40ffaf3b9 100644 --- a/rust/src/palette/methods.rs +++ b/rust/src/palette/methods.rs @@ -1,12 +1,12 @@ //! `NcPalette` methods and associated functions. -use crate::{error, NcChannel, NcColor, NcPalette, NcPaletteIndex, NcResult, NcRgb, Notcurses}; +use crate::{error, NcChannel, NcColor, NcNotcurses, NcPalette, NcPaletteIndex, NcResult, NcRgb}; impl NcPalette { /// New NcPalette. /// /// *C style function: [palette256_new()][crate::palette256_new].* - pub fn new<'a>(nc: &mut Notcurses) -> &'a mut Self { + pub fn new<'a>(nc: &mut NcNotcurses) -> &'a mut Self { unsafe { &mut *crate::palette256_new(nc) } } @@ -22,7 +22,7 @@ impl NcPalette { /// Attempts to configure the terminal with this NcPalette. /// /// *C style function: [palette256_use()][crate::palette256_use].* - pub fn r#use(&self, nc: &mut Notcurses) -> NcResult<()> { + pub fn r#use(&self, nc: &mut NcNotcurses) -> NcResult<()> { error![unsafe { crate::palette256_use(nc, self) }] } diff --git a/rust/src/plane/helpers.rs b/rust/src/plane/helpers.rs index 0e4c1136c..7272a0716 100644 --- a/rust/src/plane/helpers.rs +++ b/rust/src/plane/helpers.rs @@ -1,9 +1,9 @@ -use crate::{NcDimension, NcOffset, NcPlane, NcPlaneOptions, Notcurses}; +use crate::{NcDimension, NcNotcurses, NcOffset, NcPlane, NcPlaneOptions}; /// Helper function for a new NcPlane on C style tests. #[allow(dead_code)] pub(crate) unsafe fn ncplane_new_test<'a>( - nc: &mut Notcurses, + nc: &mut NcNotcurses, y: NcOffset, x: NcOffset, rows: NcDimension, diff --git a/rust/src/plane/methods.rs b/rust/src/plane/methods.rs index 87262002e..47b287ceb 100644 --- a/rust/src/plane/methods.rs +++ b/rust/src/plane/methods.rs @@ -4,9 +4,9 @@ use core::ptr::{null, null_mut}; use crate::{ cstring, error, error_ref, error_ref_mut, rstring, NcAlign, NcAlphaBits, NcBoxMask, NcCell, - NcChannel, NcChannelPair, NcColor, NcDimension, NcEgc, NcError, NcFadeCb, NcOffset, - NcPaletteIndex, NcPlane, NcPlaneOptions, NcResizeCb, NcResult, NcRgb, NcStyleMask, NcTime, - Notcurses, NCRESULT_ERR, + NcChannel, NcChannelPair, NcColor, NcDimension, NcEgc, NcError, NcFadeCb, NcNotcurses, + NcOffset, NcPaletteIndex, NcPlane, NcPlaneOptions, NcResizeCb, NcResult, NcRgb, NcStyleMask, + NcTime, NCRESULT_ERR, }; /// # NcPlaneOptions Constructors @@ -76,7 +76,7 @@ impl NcPlane { /// /// *C style function: [ncpile_create()][crate::ncpile_create].* pub fn new<'a>( - nc: &mut Notcurses, + nc: &mut NcNotcurses, y: NcOffset, x: NcOffset, rows: NcDimension, @@ -91,12 +91,12 @@ impl NcPlane { /// /// *C style function: [ncpile_create()][crate::ncpile_create].* pub fn with_options<'a>( - nc: &mut Notcurses, + nc: &mut NcNotcurses, options: NcPlaneOptions, ) -> NcResult<&'a mut NcPlane> { error_ref_mut![ unsafe { crate::ncpile_create(nc, &options) }, - &format!["NcPlane::with_options(Notcurses, {:?})", options] + &format!["NcPlane::with_options(NcNotcurses, {:?})", options] ] } @@ -133,7 +133,7 @@ impl NcPlane { /// The returned plane will be the top, bottom, and root of this new pile. /// /// *(No equivalent C style function)* - pub fn new_termsize<'a>(nc: &mut Notcurses) -> NcResult<&'a mut NcPlane> { + pub fn new_termsize<'a>(nc: &mut NcNotcurses) -> NcResult<&'a mut NcPlane> { let (trows, tcols) = crate::notcurses_term_dim_yx(nc); assert![(trows > 0) & (tcols > 0)]; Self::with_options( @@ -310,7 +310,7 @@ impl NcPlane { /// the provided values will be interpreted in some lossy fashion. /// /// "HP-like" terminals require setting foreground and background at the same - /// time using "color pairs"; Notcurses will manage color pairs transparently. + /// time using "color pairs"; NcNotcurses will manage color pairs transparently. /// /// *C style function: [ncplane_set_fg_rgb8()][crate::ncplane_set_fg_rgb8].* pub fn set_fg_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor) { @@ -327,7 +327,7 @@ impl NcPlane { /// the provided values will be interpreted in some lossy fashion. /// /// "HP-like" terminals require setting foreground and background at the same - /// time using "color pairs"; Notcurses will manage color pairs transparently. + /// time using "color pairs"; NcNotcurses will manage color pairs transparently. /// /// *C style function: [ncplane_set_bg_rgb8()][crate::ncplane_set_bg_rgb8].* pub fn set_bg_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor) { @@ -551,8 +551,10 @@ impl NcPlane { if egc.is_null() { return Err(NcError::with_msg( NCRESULT_ERR, - &format!("NcPlane.at_yx({}, {}, {:0X}, {:0X})", - y, x, stylemask, channels), + &format!( + "NcPlane.at_yx({}, {}, {:0X}, {:0X})", + y, x, stylemask, channels + ), )); } let egc = core::char::from_u32(unsafe { *egc } as u32).expect("wrong char"); @@ -869,7 +871,7 @@ impl NcPlane { } // ----------------------------------------------------------------------------- -/// ## NcPlane methods: `NcPlane` & `Notcurses` +/// ## NcPlane methods: `NcPlane` & `NcNotcurses` impl NcPlane { /// Duplicates this NcPlane. /// @@ -938,20 +940,14 @@ impl NcPlane { /// /// *C style function: [ncplane_above()][crate::ncplane_above].* pub fn above<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> { - error_ref_mut![ - unsafe { crate::ncplane_above(self) }, - "NcPlane.above()" - ] + error_ref_mut![unsafe { crate::ncplane_above(self) }, "NcPlane.above()"] } /// Returns the NcPlane below this one, or None if already at the bottom. /// /// *C style function: [ncplane_below()][crate::ncplane_below].* pub fn below<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> { - error_ref_mut![ - unsafe { crate::ncplane_below(self) }, - "NcPlane.below()" - ] + error_ref_mut![unsafe { crate::ncplane_below(self) }, "NcPlane.below()"] } /// Relocates this NcPlane above the `above` NcPlane, in the z-buffer. @@ -1004,18 +1000,22 @@ impl NcPlane { target_x: NcDimension, ) -> NcResult<()> { error![ - unsafe { crate::ncplane_mergedown( - source, - self, - source_y as i32, - source_x as i32, - len_y as i32, - len_x as i32, - target_y as i32, - target_x as i32, - )}, - &format!("NcPlane.mergedown(NcPlane, {}, {}, {}, {}, {}, {})", - source_y, source_x, len_y, len_x, target_y, target_x) + unsafe { + crate::ncplane_mergedown( + source, + self, + source_y as i32, + source_x as i32, + len_y as i32, + len_x as i32, + target_y as i32, + target_x as i32, + ) + }, + &format!( + "NcPlane.mergedown(NcPlane, {}, {}, {}, {}, {}, {})", + source_y, source_x, len_y, len_x, target_y, target_x + ) ] } @@ -1044,10 +1044,7 @@ impl NcPlane { // // TODO: CHECK: what happens when it's bound to itself. pub fn parent<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> { - error_ref_mut![ - unsafe { crate::ncplane_parent(self) }, - "NcPlane.parent()" - ] + error_ref_mut![unsafe { crate::ncplane_parent(self) }, "NcPlane.parent()"] } /// Gets the parent to which this NcPlane is bound, if any. @@ -1104,7 +1101,10 @@ impl NcPlane { /// /// *C style function: [ncpile_rasterize()][crate::ncpile_rasterize].* pub fn rasterize<'a>(&mut self) -> NcResult<()> { - error![unsafe { crate::ncpile_rasterize(self) }, "NcPlane.rasterize()"] + error![ + unsafe { crate::ncpile_rasterize(self) }, + "NcPlane.rasterize()" + ] } /// Renders the pile of which this NcPlane is a part. @@ -1116,20 +1116,20 @@ impl NcPlane { error![unsafe { crate::ncpile_render(self) }, "NcPlane.render()"] } - /// Gets a mutable reference to the [Notcurses] context of this NcPlane. + /// Gets a mutable reference to the [NcNotcurses] context of this NcPlane. /// /// *C style function: [ncplane_notcurses()][crate::ncplane_notcurses].* - pub fn notcurses<'a>(&mut self) -> NcResult<&'a mut Notcurses> { + pub fn notcurses<'a>(&mut self) -> NcResult<&'a mut NcNotcurses> { error_ref_mut![ unsafe { crate::ncplane_notcurses(self) }, "NcPlane.notcurses()" ] } - /// Gets an immutable reference to the [Notcurses] context of this NcPlane. + /// Gets an immutable reference to the [NcNotcurses] context of this NcPlane. /// /// *C style function: [ncplane_notcurses_const()][crate::ncplane_notcurses_const].* - pub fn notcurses_const<'a>(&self) -> NcResult<&'a Notcurses> { + pub fn notcurses_const<'a>(&self) -> NcResult<&'a NcNotcurses> { error_ref![ unsafe { crate::ncplane_notcurses_const(self) }, "NcPlane.notcurses()" @@ -1339,19 +1339,23 @@ impl NcPlane { x_len: NcDimension, ) -> NcResult<()> { error![ - unsafe { crate::ncplane_resize( - self, - keep_y as i32, - keep_x as i32, - keep_len_y as i32, - keep_len_x as i32, - y_off as i32, - x_off as i32, - y_len as i32, - x_len as i32, - )}, - &format!("NcPlane.resize({}, {}, {}, {}, {}, {}, {}, {})", - keep_y, keep_x, keep_len_y, keep_len_x, y_off, x_off, y_len, x_len) + unsafe { + crate::ncplane_resize( + self, + keep_y as i32, + keep_x as i32, + keep_len_y as i32, + keep_len_x as i32, + y_off as i32, + x_off as i32, + y_len as i32, + x_len as i32, + ) + }, + &format!( + "NcPlane.resize({}, {}, {}, {}, {}, {}, {}, {})", + keep_y, keep_x, keep_len_y, keep_len_x, y_off, x_off, y_len, x_len + ) ] } diff --git a/rust/src/stats.rs b/rust/src/stats.rs index a91dd5e5a..9db2281a7 100644 --- a/rust/src/stats.rs +++ b/rust/src/stats.rs @@ -1,6 +1,6 @@ //! `NcStats` -use crate::Notcurses; +use crate::NcNotcurses; /// notcurses runtime statistics pub type NcStats = crate::bindings::ffi::ncstats; @@ -8,17 +8,17 @@ pub type NcStats = crate::bindings::ffi::ncstats; /// # `NcStats` Methods. impl NcStats { /// Allocates an NcStats object. - pub fn new<'a>(nc: &'a Notcurses) -> &'a mut Self { + pub fn new<'a>(nc: &'a NcNotcurses) -> &'a mut Self { unsafe { &mut *crate::notcurses_stats_alloc(nc) } } - /// Acquires an atomic snapshot of the Notcurses object's stats. - pub fn stats(&mut self, nc: &Notcurses) { + /// Acquires an atomic snapshot of the NcNotcurses object's stats. + pub fn stats(&mut self, nc: &NcNotcurses) { unsafe { crate::notcurses_stats(nc, self) } } /// Resets all cumulative stats (immediate ones are not reset). - pub fn reset(&mut self, nc: &mut Notcurses) { + pub fn reset(&mut self, nc: &mut NcNotcurses) { unsafe { crate::notcurses_stats_reset(nc, self) } } }