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.
This commit is contained in:
joseLuís 2021-01-02 19:45:15 +01:00
parent af07822d35
commit 6b2805937d
22 changed files with 395 additions and 248 deletions

View File

@ -16,10 +16,8 @@ fn main() -> NcResult<()> {
let rows = ncd.dim_y(); let rows = ncd.dim_y();
println!("terminal size (rows, cols): {}, {}", rows, cols); println!("terminal size (rows, cols): {}, {}", rows, cols);
let mut channels = NcChannelPair::combine( let mut channels =
NcChannel::with_rgb(0xAA2244), NcChannelPair::combine(NcChannel::with_rgb(0xAA2244), NcChannel::with_rgb(0x112233));
NcChannel::with_rgb(0x112233),
);
ncd.putstr(channels, "The current coordinates are")?; ncd.putstr(channels, "The current coordinates are")?;
for _n in 0..40 { for _n in 0..40 {
@ -41,7 +39,9 @@ fn main() -> NcResult<()> {
ncd.putstr(channels, &format!(" ({},{})\n", cy, cx))?; ncd.putstr(channels, &format!(" ({},{})\n", cy, cx))?;
sleep![1]; 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 { for word in sentence {
channels.set_fg_rgb(channels.fg_rgb().wrapping_sub(0x050505)); channels.set_fg_rgb(channels.fg_rgb().wrapping_sub(0x050505));
channels.set_bg_rgb(channels.bg_rgb().wrapping_add(0x090909)); channels.set_bg_rgb(channels.bg_rgb().wrapping_add(0x090909));

View File

@ -4,8 +4,8 @@
//! //!
//! NOTE: This example uses the C style with functions. //! NOTE: This example uses the C style with functions.
use libnotcurses_sys::*;
use core::ptr::{null, null_mut}; use core::ptr::{null, null_mut};
use libnotcurses_sys::*;
fn main() { fn main() {
unsafe { unsafe {
@ -29,8 +29,10 @@ fn render_image(ncd: &mut NcDirect, blit: NcBlitter) {
NCSCALE_NONE, NCSCALE_NONE,
) != 0 ) != 0
{ {
panic!("ERROR: ncdirect_render_image(). Make sure you \ panic!(
are running this example from the examples folder"); "ERROR: ncdirect_render_image(). Make sure you \
are running this example from the examples folder"
);
} }
} }
} }

View File

@ -17,16 +17,13 @@ fn main() -> NcResult<()> {
Ok(()) Ok(())
} }
fn render_image(ncd: &mut NcDirect, blit: NcBlitter) -> NcResult<()>{ fn render_image(ncd: &mut NcDirect, blit: NcBlitter) -> NcResult<()> {
if let Err(nc_error) = ncd.render_image( if let Err(nc_error) = ncd.render_image("image-16x16.png", NCALIGN_CENTER, blit, NCSCALE_NONE) {
"image-16x16.png", return Err(NcError::with_msg(
NCALIGN_CENTER, nc_error.int,
blit,
NCSCALE_NONE,
) {
return Err(NcError::with_msg(nc_error.int,
"ERROR: ncdirect_render_image(). Make sure you \ "ERROR: ncdirect_render_image(). Make sure you \
are running this example from the examples folder")); are running this example from the examples folder",
));
} }
Ok(()) Ok(())
} }

View File

@ -1,17 +1,15 @@
use libnotcurses_sys::*; use libnotcurses_sys::*;
fn main() -> NcResult<()> { fn main() -> NcResult<()> {
let nc = Notcurses::new()?; let mut nc = Notcurses::new()?;
let stdplane = nc.stdplane()?; let stdplane = nc.stdplane()?;
for ch in "Initializing cells...".chars() { for ch in "Initializing cells...".chars() {
let cell = NcCell::with_char7b(ch); let cell = NcCell::with_char7b(ch);
stdplane.putc(&cell)?; stdplane.putc(&cell)?;
sleep![0, 40]; rsleep![&mut nc, 0, 40];
nc.render()?;
} }
sleep![0, 900]; sleep![0, 900];
nc.stop()?;
Ok(()) Ok(())
} }

View File

@ -6,10 +6,8 @@
use libnotcurses_sys::*; use libnotcurses_sys::*;
fn main() -> NcResult<()> { fn main() -> NcResult<()> {
let nc = Notcurses::with_flags( let mut nc = Notcurses::with_flags(
NCOPTION_SUPPRESS_BANNERS NCOPTION_SUPPRESS_BANNERS | NCOPTION_NO_WINCH_SIGHANDLER | NCOPTION_NO_QUIT_SIGHANDLERS,
| NCOPTION_NO_WINCH_SIGHANDLER
| NCOPTION_NO_QUIT_SIGHANDLERS
)?; )?;
// doesn't seem to be necessary: // doesn't seem to be necessary:
@ -21,13 +19,13 @@ fn main() -> NcResult<()> {
let mut input = NcInput::new_empty(); let mut input = NcInput::new_empty();
loop { loop {
let key = notcurses_getc_nblock(nc, &mut input); let key = notcurses_getc_nblock(&mut nc, &mut input);
if key as i32 != -1 { if key as i32 != -1 {
println!("'{0}' ({1:x})\n{2:?}", key, key as u32, input); println!("'{0}' ({1:x})\n{2:?}", key, key as u32, input);
} }
rsleep![nc, 0, 10]; rsleep![&mut nc, 0, 10];
match key { match key {
NCKEY_F01 => break, NCKEY_F01 => break,
@ -37,7 +35,7 @@ fn main() -> NcResult<()> {
println!("\nExiting..."); println!("\nExiting...");
rsleep![nc, 1, 500]; rsleep![&mut nc, 1, 500];
nc.stop()?; nc.stop()?;
Ok(()) Ok(())
} }

View File

@ -3,8 +3,7 @@
use libnotcurses_sys::*; use libnotcurses_sys::*;
fn main() -> NcResult<()> { fn main() -> NcResult<()> {
let mut nc = Notcurses::new()?;
let nc = Notcurses::new()?;
let plane = nc.stdplane()?; let plane = nc.stdplane()?;
plane.set_scrolling(true); plane.set_scrolling(true);
@ -14,9 +13,10 @@ fn main() -> NcResult<()> {
plane.putchar(wc)?; plane.putchar(wc)?;
wc = core::char::from_u32(wc as u32 + 1).expect("invalid char"); wc = core::char::from_u32(wc as u32 + 1).expect("invalid char");
if wc == '\u{9fa5}' { // 龣 // 龣
if wc == '\u{9fa5}' {
wc = '\u{4e00}'; wc = '\u{4e00}';
} }
rsleep![nc, 0, 0, 50]; rsleep![&mut nc, 0, 0, 30];
} }
} }

View File

@ -3,7 +3,7 @@
use libnotcurses_sys::*; use libnotcurses_sys::*;
fn main() -> NcResult<()> { fn main() -> NcResult<()> {
let nc = Notcurses::new()?; let mut nc = Notcurses::new()?;
nc.mouse_enable()?; nc.mouse_enable()?;
let mut demo_items = [ let mut demo_items = [
@ -55,7 +55,7 @@ fn main() -> NcResult<()> {
" -=+ menu poc. press q to exit +=-", " -=+ menu poc. press q to exit +=-",
)?; )?;
run_menu(nc, menu_top)?; run_menu(&mut nc, menu_top)?;
stdplane.erase(); // is this needed? stdplane.erase(); // is this needed?
@ -67,9 +67,8 @@ fn main() -> NcResult<()> {
mopts.flags |= NCMENU_OPTION_BOTTOM; mopts.flags |= NCMENU_OPTION_BOTTOM;
let menu_bottom = NcMenu::new(stdplane, mopts)?; let menu_bottom = NcMenu::new(stdplane, mopts)?;
run_menu(nc, menu_bottom)?; run_menu(&mut nc, menu_bottom)?;
nc.stop()?;
Ok(()) Ok(())
} }
@ -106,7 +105,7 @@ fn run_menu(nc: &mut Notcurses, menu: &mut NcMenu) -> NcResult<()> {
menu.destroy()?; menu.destroy()?;
selplane.destroy()?; selplane.destroy()?;
return Ok(()); return Ok(());
}, }
NCKEY_ENTER => { NCKEY_ENTER => {
if let Some(selection) = menu.selected(Some(&mut ni)) { if let Some(selection) = menu.selected(Some(&mut ni)) {
match selection.as_ref() { match selection.as_ref() {
@ -115,11 +114,11 @@ fn run_menu(nc: &mut Notcurses, menu: &mut NcMenu) -> NcResult<()> {
selplane.destroy()?; selplane.destroy()?;
return Ok(()); return Ok(());
} }
_ => () _ => (),
} }
} }
} }
_ => () _ => (),
} }
} }

View File

@ -3,10 +3,10 @@
use libc::strcmp; use libc::strcmp;
use crate::{ use crate::{
cstring, cell_release, NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcEgc, NcIntResult, cell_release, cstring, NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcEgc,
NcPaletteIndex, NcPlane, NcRgb, NcStyleMask, NCCELL_ALPHA_OPAQUE, NCCELL_BGDEFAULT_MASK, NcIntResult, NcPaletteIndex, NcPlane, NcRgb, NcStyleMask, NCCELL_ALPHA_OPAQUE,
NCCELL_BG_PALETTE, NCCELL_FGDEFAULT_MASK, NCCELL_FG_PALETTE, NCCELL_NOBACKGROUND_MASK, NCCELL_BGDEFAULT_MASK, NCCELL_BG_PALETTE, NCCELL_FGDEFAULT_MASK, NCCELL_FG_PALETTE,
NCCELL_WIDEASIAN_MASK, NCRESULT_ERR, NCRESULT_OK, NCSTYLE_MASK, NCCELL_NOBACKGROUND_MASK, NCCELL_WIDEASIAN_MASK, NCRESULT_ERR, NCRESULT_OK, NCSTYLE_MASK,
}; };
// Alpha ----------------------------------------------------------------------- // Alpha -----------------------------------------------------------------------

View File

@ -10,9 +10,8 @@ fn constructors() -> crate::NcResult<()> {
let _c1 = NcCell::new(); let _c1 = NcCell::new();
let _c2 = NcCell::with_char7b('C'); let _c2 = NcCell::with_char7b('C');
let nc = Notcurses::new()?; let mut nc = Notcurses::new()?;
let plane = NcPlane::new(nc, 0, 0, 10, 10)?; let plane = NcPlane::new(&mut nc, 0, 0, 10, 10)?;
let _c3 = NcCell::with_char('௵', plane); let _c3 = NcCell::with_char('௵', plane);
nc.stop()?;
Ok(()) Ok(())
} }

View File

@ -164,7 +164,10 @@ impl NcDirect {
pub fn palette_size(&self) -> NcResult<u32> { pub fn palette_size(&self) -> NcResult<u32> {
let res = unsafe { crate::ncdirect_palette_size(self) }; let res = unsafe { crate::ncdirect_palette_size(self) };
if res == 1 { 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) Ok(res)
} }
@ -550,8 +553,10 @@ impl NcDirect {
ctlword, ctlword,
) )
}, },
&format!("NcDirect.box({:0X}, {:0X}, {:0X}, {:0X}, {:?}, {}, {}, {})", &format!(
ul, ur, ll, lr, wchars, y_len, x_len, ctlword) "NcDirect.box({:0X}, {:0X}, {:0X}, {:0X}, {:?}, {}, {}, {})",
ul, ur, ll, lr, wchars, y_len, x_len, ctlword
)
] ]
} }

View File

@ -11,7 +11,7 @@
use std::ffi::c_void; 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. /// 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'. /// The recommended absolute display time target is passed in 'tspec'.
pub type NcFadeCb = Option< 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 /// Context for a palette fade operation

View File

@ -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/) //! 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 //! ```rust
//! use libnotcurses_sys::*; //! use libnotcurses_sys::*;
//! //!
//! fn main() -> NcResult<()> { //! fn main() -> NcResult<()> {
//! let nc = Notcurses::without_altscreen()?; //! let mut nc = Notcurses::with_flags(NCOPTION_NO_ALTERNATE_SCREEN)?;
//! let plane = nc.stdplane()?; //! let plane = nc.stdplane()?;
//! plane.putstr("hello world")?; //! plane.putstr("hello world")?;
//! nc.render()?; //! nc.render()?;
//! nc.stop()?;
//! Ok(()) //! 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 //! Notcurses implements the [Drop], [AsRef], [AsMut], [Deref][std::ops::Deref]
//! to (de)reference mutable pointers. //! & [DerefMut][std::ops::DerefMut] traits.
//! 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.
//! //!
//! There are plans to manually wrap all the C API functions, in order to //! Most methods are directly implemented for NcNotcurses,
//! achieve better ergonomics and consistent syntax. //! and automatically available also from Notcurses.
//! ```rust
//! use libnotcurses_sys::*;
//! //!
//! fn main() { //! The destructor ([notcurses_stop()]) is called automatically at the end
//! let options = NotcursesOptions::with_flags(NCOPTION_NO_ALTERNATE_SCREEN); //! of its scope, so you don't ever have to call it by hand.
//! unsafe { //!
//! let nc = notcurses_init(&options, core::ptr::null_mut()); //! The Rust style methods manage errors by means of returning an
//! let plane = notcurses_stdplane(nc); //! [`NcResult`]`<T, `[`NcError`]`>`, for painless handling.
//! ncplane_putstr(&mut *plane, "hello world"); //!
//! notcurses_render(nc); //! ## 2. The C way
//! notcurses_stop(nc); //!
//! } //! 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 //! ```rust
//! use core::ptr::{null, null_mut}; //! use core::ptr::{null, null_mut};
//! use libnotcurses_sys::*; //! use libnotcurses_sys::*;
@ -60,6 +62,7 @@
//! margin_l: 0, //! margin_l: 0,
//! flags: NCOPTION_NO_ALTERNATE_SCREEN, //! flags: NCOPTION_NO_ALTERNATE_SCREEN,
//! }; //! };
//! // NOTE: there's missing manual checking of return values for errors.
//! unsafe { //! unsafe {
//! let nc = notcurses_init(&options, null_mut()); //! let nc = notcurses_init(&options, null_mut());
//! let plane = notcurses_stdplane(nc); //! let plane = notcurses_stdplane(nc);
@ -69,18 +72,10 @@
//! } //! }
//! //!
//! ``` //! ```
//! ## About this library //! It requires the use of unsafe.
//! //!
//! 1. There are no Drop trait implementations, therefore you must manually stop //! The C style functions handle errors by the means of returning an i32 value
//! each context before it goes out of scope ([Notcurses], [NcDirect]), and //! aliased to [NcIntResult].
//! 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].
//!
//!
//! [Macros][#macros] are
//! //!
//! ## The `notcurses` C API docs //! ## The `notcurses` C API docs
//! //!

View File

@ -5,7 +5,7 @@
#[allow(unused_imports)] #[allow(unused_imports)]
// enjoy briefer doc comments // 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 ------------------------------------------------ // 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. /// calls the sleep macro with the rest of the arguments.
/// ///
/// Returns [NcResult]. /// Returns [NcResult].
@ -42,7 +42,7 @@ macro_rules! sleep {
macro_rules! rsleep { macro_rules! rsleep {
($nc:expr, $( $sleep_args:expr),+ ) => { ($nc:expr, $( $sleep_args:expr),+ ) => {
// Rust style, with methods & NcResult // Rust style, with methods & NcResult
Notcurses::render($nc)?; NcNotcurses::render($nc)?;
sleep![$( $sleep_args ),+]; sleep![$( $sleep_args ),+];
}; };
($nc:expr, $( $sleep_args:expr),+ ,) => { ($nc:expr, $( $sleep_args:expr),+ ,) => {
@ -91,7 +91,7 @@ macro_rules! cstring_mut {
macro_rules! rstring { macro_rules! rstring {
($s:expr) => { ($s:expr) => {
unsafe { std::ffi::CStr::from_ptr($s).to_str().unwrap() } unsafe { std::ffi::CStr::from_ptr($s).to_str().unwrap() }
// possible alternative // possible alternative:
// unsafe { std::ffi::CStr::from_ptr($s).to_string_lossy() } // unsafe { std::ffi::CStr::from_ptr($s).to_string_lossy() }
}; };
} }
@ -203,3 +203,14 @@ macro_rules! error_str {
error_str![$str, ""]; error_str![$str, ""];
}; };
} }
/// Returns an NcResult<Self { raw: T }> from an NcResult<T>.
#[macro_export]
macro_rules! raw_wrap {
($res:expr) => {
match $res {
Ok(raw) => return Ok(Self { raw }),
Err(e) => return Err(e),
}
};
}

View File

@ -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)] #[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( &mut *notcurses_init(
&NotcursesOptions::with_flags(NCOPTION_SUPPRESS_BANNERS), &NcNotcursesOptions::with_flags(NCOPTION_SUPPRESS_BANNERS),
core::ptr::null_mut(), core::ptr::null_mut(),
) )
} }

View File

@ -1,22 +1,22 @@
//! `Notcurses*` methods and associated functions. //! `NcNotcurses*` methods and associated functions.
use core::ptr::{null, null_mut}; use core::ptr::{null, null_mut};
use crate::{ use crate::{
cstring, error, error_ref_mut, notcurses_init, rstring, NcAlign, NcBlitter, NcChannelPair, cstring, error, error_ref_mut, notcurses_init, rstring, NcAlign, NcBlitter, NcChannelPair,
NcDimension, NcEgc, NcError, NcFile, NcInput, NcLogLevel, NcPlane, NcResult, NcScale, NcDimension, NcEgc, NcError, NcFile, NcInput, NcLogLevel, NcNotcurses, NcNotcursesOptions,
NcSignalSet, NcStats, NcStyleMask, NcTime, Notcurses, NotcursesOptions, NcPlane, NcResult, NcScale, NcSignalSet, NcStats, NcStyleMask, NcTime,
NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS, NCRESULT_ERR, NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS, NCRESULT_ERR,
}; };
/// # `NotcursesOptions` Constructors /// # `NcNotcursesOptions` Constructors
impl NotcursesOptions { impl NcNotcursesOptions {
/// New NotcursesOptions. /// New NcNotcursesOptions.
pub const fn new() -> Self { pub const fn new() -> Self {
Self::with_all_options(0, 0, 0, 0, 0, 0) Self::with_all_options(0, 0, 0, 0, 0, 0)
} }
/// New NotcursesOptions, with margins. /// New NcNotcursesOptions, with margins.
pub const fn with_margins( pub const fn with_margins(
top: NcDimension, top: NcDimension,
right: NcDimension, right: NcDimension,
@ -26,12 +26,12 @@ impl NotcursesOptions {
Self::with_all_options(0, top, right, bottom, left, 0) 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 { pub const fn with_flags(flags: u64) -> Self {
Self::with_all_options(0, 0, 0, 0, 0, flags) Self::with_all_options(0, 0, 0, 0, 0, flags)
} }
/// New NotcursesOptions, with all the options. /// New NcNotcursesOptions, with all the options.
/// ///
/// ## Arguments /// ## Arguments
/// ///
@ -83,51 +83,46 @@ impl NotcursesOptions {
} }
} }
/// # `Notcurses` Constructors /// # `NcNotcurses` Constructors
impl Notcurses { impl NcNotcurses {
/// New Notcurses (without banners). /// New NcNotcurses (without banners).
pub fn new<'a>() -> NcResult<&'a mut Notcurses> { pub fn new<'a>() -> NcResult<&'a mut NcNotcurses> {
Self::with_flags(NCOPTION_SUPPRESS_BANNERS) Self::with_flags(NCOPTION_SUPPRESS_BANNERS)
} }
/// New Notcurses, with banners. /// New NcNotcurses, with banners.
/// ///
/// This is the default in the C library. /// 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) Self::with_flags(0)
} }
/// New Notcurses, without an alternate screen (nor banners). /// New NcNotcurses, without an alternate screen (nor banners).
pub fn without_altscreen<'a>() -> NcResult<&'a mut Notcurses> { pub fn without_altscreen<'a>() -> NcResult<&'a mut NcNotcurses> {
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> {
Self::with_flags(NCOPTION_NO_ALTERNATE_SCREEN | NCOPTION_SUPPRESS_BANNERS) Self::with_flags(NCOPTION_NO_ALTERNATE_SCREEN | NCOPTION_SUPPRESS_BANNERS)
} }
/// New Notcurses, expects `NCOPTION_*` flags. /// New NcNotcurses, expects `NCOPTION_*` flags.
pub fn with_flags<'a>(flags: u64) -> NcResult<&'a mut Notcurses> { pub fn with_flags<'a>(flags: u64) -> NcResult<&'a mut NcNotcurses> {
Self::with_options(NotcursesOptions::with_flags(flags)) Self::with_options(NcNotcursesOptions::with_flags(flags))
} }
/// New Notcurses, expects [NotcursesOptions]. /// New NcNotcurses, expects [NcNotcursesOptions].
pub fn with_options<'a>(options: NotcursesOptions) -> NcResult<&'a mut Notcurses> { pub fn with_options<'a>(options: NcNotcursesOptions) -> NcResult<&'a mut NcNotcurses> {
let res = unsafe { notcurses_init(&options, null_mut()) }; 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. /// New NcNotcurses, expects [NcLogLevel] and flags.
pub fn with_debug<'a>(loglevel: NcLogLevel, flags: u64) -> NcResult<&'a mut Notcurses> { pub fn with_debug<'a>(loglevel: NcLogLevel, flags: u64) -> NcResult<&'a mut NcNotcurses> {
Self::with_options(NotcursesOptions::with_all_options( Self::with_options(NcNotcursesOptions::with_all_options(
loglevel, 0, 0, 0, 0, flags, loglevel, 0, 0, 0, 0, flags,
)) ))
} }
} }
/// # `Notcurses` methods /// # `NcNotcurses` methods
impl Notcurses { impl NcNotcurses {
/// Returns the offset into `availcols` at which `cols` ought be output given /// Returns the offset into `availcols` at which `cols` ought be output given
/// the requirements of `align`. /// the requirements of `align`.
/// ///
@ -135,6 +130,8 @@ impl Notcurses {
/// [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED] or invalid [NcAlign]. /// [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED] or invalid [NcAlign].
/// ///
/// *C style function: [notcurses_align()][crate::notcurses_align].* /// *C style function: [notcurses_align()][crate::notcurses_align].*
//
// TODO: handle error rightfully.
pub fn align(availcols: NcDimension, align: NcAlign, cols: NcDimension) -> NcResult<()> { pub fn align(availcols: NcDimension, align: NcAlign, cols: NcDimension) -> NcResult<()> {
error![crate::notcurses_align(availcols, align, cols)] 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) }] 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 /// Output is freeform, and subject to change. It includes geometry of all
/// planes, from all piles. /// planes, from all piles.
@ -356,7 +353,7 @@ impl Notcurses {
} else { } else {
error![ error![
-1, -1,
&format!("Notcurses.getc_blocking({:?})", input_txt), &format!("NcNotcurses.getc_blocking({:?})", input_txt),
res res
] ]
} }
@ -365,7 +362,7 @@ impl Notcurses {
/// Gets a file descriptor suitable for input event poll()ing. /// Gets a file descriptor suitable for input event poll()ing.
/// ///
/// When this descriptor becomes available, you can call /// 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 /// This file descriptor is not necessarily the file descriptor associated
/// with stdin (but it might be!). /// 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, /// There can be either a single number, which will define all margins equally,
/// or there can be four numbers separated by commas. /// or there can be four numbers separated by commas.
/// ///
/// *C style function: [notcurses_lex_margins()][crate::notcurses_lex_margins].* /// *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) }] 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 /// Enable the mouse in "button-event tracking" mode with focus detection
/// and UTF8-style extended coordinates. /// 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].* /// *C style function: [notcurses_mouse_enable()][crate::notcurses_mouse_enable].*
pub fn mouse_enable(&mut self) -> NcResult<()> { pub fn mouse_enable(&mut self) -> NcResult<()> {
error![ error![
unsafe { crate::notcurses_mouse_enable(self) }, 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., /// Refreshes the physical screen to match what was last rendered (i.e.,
/// without reflecting any changes since the last call to /// 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 /// 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 /// [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<()> { pub fn render(&mut self) -> NcResult<()> {
error![ error![
unsafe { crate::notcurses_render(self) }, unsafe { crate::notcurses_render(self) },
"Notcurses.render()" "NcNotcurses.render()"
] ]
} }
/// Performs the rendering and rasterization portion of /// 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. /// out to the terminal.
/// ///
/// Using this function, the user can control the writeout process, /// 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'. /// 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. /// nothing will be written.
/// ///
/// *C style function: [notcurses_render_to_file()][crate::notcurses_render_to_file].* /// *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()) }] 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].* /// *C style function: [notcurses_stats()][crate::notcurses_stats].*
pub fn stats(&mut self, stats: &mut NcStats) { pub fn stats(&mut self, stats: &mut NcStats) {
@ -525,7 +522,7 @@ impl Notcurses {
/// Allocates an ncstats object. /// Allocates an ncstats object.
/// ///
/// Use this rather than allocating your own, since future versions of /// 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].* /// *C style function: [notcurses_stats_alloc()][crate::notcurses_stats_alloc].*
pub fn stats_alloc<'a>(&'a mut self) -> &'a mut NcStats { pub fn stats_alloc<'a>(&'a mut self) -> &'a mut NcStats {
@ -554,7 +551,7 @@ impl Notcurses {
// crate::notcurses_stddim_yx(self, y, x) // 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! // /// bonus dimensions written to non-NULL y/x!
// /// // ///
// /// *C style function: [notcurses_stddim_yx()][crate::notcurses_stddim_yx].* // /// *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> { pub fn stdplane<'a>(&mut self) -> NcResult<&'a mut NcPlane> {
error_ref_mut![ error_ref_mut![
unsafe { crate::notcurses_stdplane(self) }, unsafe { crate::notcurses_stdplane(self) },
"Notcurses.stdplane()" "NcNotcurses.stdplane()"
] ]
} }
@ -590,7 +587,7 @@ impl Notcurses {
unsafe { &*crate::notcurses_stdplane_const(self) } unsafe { &*crate::notcurses_stdplane_const(self) }
} }
/// Destroys the Notcurses context. /// Destroys the NcNotcurses context.
/// ///
/// *C style function: [notcurses_stop()][crate::notcurses_stop].* /// *C style function: [notcurses_stop()][crate::notcurses_stop].*
pub fn stop(&mut self) -> NcResult<()> { pub fn stop(&mut self) -> NcResult<()> {
@ -637,14 +634,14 @@ impl Notcurses {
unsafe { &mut *crate::notcurses_top(self) } 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].* /// *C style function: [notcurses_version()][crate::notcurses_version].*
pub fn version() -> String { pub fn version() -> String {
rstring![crate::notcurses_version()].to_string() rstring![crate::notcurses_version()].to_string()
} }
/// Returns the running Notcurses version components /// Returns the running NcNotcurses version components
/// (major, minor, patch, tweak). /// (major, minor, patch, tweak).
/// ///
/// *C style function: [notcurses_version_components()][crate::notcurses_version_components].* /// *C style function: [notcurses_version_components()][crate::notcurses_version_components].*

View File

@ -1,4 +1,4 @@
//! `Notcurses` //! `NcNotcurses`
// functions already exported by bindgen : 42 // functions already exported by bindgen : 42
// ------------------------------------------ // ------------------------------------------
@ -67,20 +67,22 @@ mod test;
mod helpers; mod helpers;
mod methods; mod methods;
mod reimplemented; mod reimplemented;
mod wrapper;
#[allow(unused_imports)] #[allow(unused_imports)]
pub(crate) use helpers::*; pub(crate) use helpers::*;
pub use reimplemented::*; pub use reimplemented::*;
pub use wrapper::*;
/// The main struct of the TUI library (full mode) /// NcNotcurses builds atop the terminfo abstraction layer to
///
/// Notcurses builds atop the terminfo abstraction layer to
/// provide reasonably portable vivid character displays. /// 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`] /// Options struct for [`NcNotcurses`]
pub type NotcursesOptions = crate::bindings::ffi::notcurses_options; pub type NcNotcursesOptions = crate::bindings::ffi::notcurses_options;
/// Do not call setlocale() /// Do not call setlocale()
/// ///
@ -96,17 +98,17 @@ pub const NCOPTION_INHIBIT_SETLOCALE: u64 = crate::bindings::ffi::NCOPTION_INHIB
/// Do not enter alternate mode. /// 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. /// of the "alternate screen". This flag inhibits use of smcup/rmcup.
pub const NCOPTION_NO_ALTERNATE_SCREEN: u64 = pub const NCOPTION_NO_ALTERNATE_SCREEN: u64 =
crate::bindings::ffi::NCOPTION_NO_ALTERNATE_SCREEN as u64; crate::bindings::ffi::NCOPTION_NO_ALTERNATE_SCREEN as u64;
/// Do not modify the font. /// 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 /// glyphs (especially on the Linux console). If this is set, no such
/// modifications will be made. Note that font changes will not affect anything /// 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; pub const NCOPTION_NO_FONT_CHANGES: u64 = crate::bindings::ffi::NCOPTION_NO_FONT_CHANGES as u64;
/// Do not handle SIG{ING, SEGV, ABRT, QUIT} /// Do not handle SIG{ING, SEGV, ABRT, QUIT}
@ -127,7 +129,7 @@ pub const NCOPTION_NO_WINCH_SIGHANDLER: u64 =
/// Do not print banners /// 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. /// info in notcurses_stop(). This inhibits that output.
pub const NCOPTION_SUPPRESS_BANNERS: u64 = crate::bindings::ffi::NCOPTION_SUPPRESS_BANNERS as u64; 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 ------------------------------------------------------------------ // 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 /// 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`. /// `NCOPTION_SUPPRESS_BANNERS`.
/// Note that if stderr is connected to the same terminal on which we're /// Note that if stderr is connected to the same terminal on which we're
/// rendering, any kind of logging will disrupt the output. /// rendering, any kind of logging will disrupt the output.

View File

@ -3,8 +3,8 @@
use core::ptr::{null, null_mut}; use core::ptr::{null, null_mut};
use crate::{ use crate::{
NcAlign, NcDimension, NcError, NcInput, NcOffset, NcPlane, NcResult, NcSignalSet, NcTime, NcAlign, NcDimension, NcError, NcInput, NcNotcurses, NcOffset, NcPlane, NcResult, NcSignalSet,
Notcurses, NCALIGN_CENTER, NCALIGN_LEFT, NCALIGN_RIGHT, NCRESULT_ERR, NCRESULT_MAX, NcTime, NCALIGN_CENTER, NCALIGN_LEFT, NCALIGN_RIGHT, NCRESULT_ERR, NCRESULT_MAX,
}; };
/// Returns the offset into `availcols` at which `cols` ought be output given /// 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] /// Returns `-`[`NCRESULT_MAX`] if [NCALIGN_UNALIGNED][crate::NCALIGN_UNALIGNED]
/// or invalid [NcAlign]. /// or invalid [NcAlign].
/// ///
/// *Method: Notcurses.[align()][Notcurses#method.align].* /// *Method: NcNotcurses.[align()][NcNotcurses#method.align].*
#[inline] #[inline]
pub fn notcurses_align(availcols: NcDimension, align: NcAlign, cols: NcDimension) -> NcOffset { pub fn notcurses_align(availcols: NcDimension, align: NcAlign, cols: NcDimension) -> NcOffset {
if align == NCALIGN_LEFT { 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. /// 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. // TODO: use from_u32 & return Option.
#[inline] #[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 { unsafe {
let mut sigmask = NcSignalSet::new(); let mut sigmask = NcSignalSet::new();
sigmask.fillset(); 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. /// 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] #[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; let input_ptr;
if let Some(i) = input { if let Some(i) = input {
input_ptr = i as *mut _; 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 /// [notcurses_stdplane()][crate::notcurses_stdplane], plus free bonus
/// dimensions written to non-NULL y/x! /// 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] #[inline]
pub fn notcurses_stddim_yx<'a>( pub fn notcurses_stddim_yx<'a>(
nc: &'a mut Notcurses, nc: &'a mut NcNotcurses,
y: &mut NcDimension, y: &mut NcDimension,
x: &mut NcDimension, x: &mut NcDimension,
) -> NcResult<&'a mut NcPlane> { ) -> NcResult<&'a mut NcPlane> {
@ -95,10 +95,10 @@ pub fn notcurses_stddim_yx<'a>(
/// [notcurses_stdplane_const()][crate::notcurses_stdplane_const], plus free /// [notcurses_stdplane_const()][crate::notcurses_stdplane_const], plus free
/// bonus dimensions written to non-NULL y/x! /// 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] #[inline]
pub fn notcurses_stddim_yx_const<'a>( pub fn notcurses_stddim_yx_const<'a>(
nc: &'a Notcurses, nc: &'a NcNotcurses,
y: &mut NcDimension, y: &mut NcDimension,
x: &mut NcDimension, x: &mut NcDimension,
) -> NcResult<&'a NcPlane> { ) -> 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. /// 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] #[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); let (mut y, mut x) = (0, 0);
unsafe { unsafe {
crate::ncplane_dim_yx(crate::notcurses_stdplane_const(nc), &mut y, &mut x); crate::ncplane_dim_yx(crate::notcurses_stdplane_const(nc), &mut y, &mut x);

View File

@ -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<NcNotcurses> for Notcurses<'a> {
fn as_ref(&self) -> &NcNotcurses {
self.raw
}
}
impl<'a> AsMut<NcNotcurses> 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<Self> {
raw_wrap![NcNotcurses::new()]
}
/// New Notcurses, without banners.
pub fn with_banners() -> NcResult<Self> {
raw_wrap![NcNotcurses::with_banners()]
}
/// New Notcurses, without an alternate screen (nor banners).
pub fn without_altscreen() -> NcResult<Self> {
raw_wrap![NcNotcurses::without_altscreen()]
}
/// New Notcurses, expects `NCOPTION_*` flags.
pub fn with_flags(flags: u64) -> NcResult<Self> {
raw_wrap![NcNotcurses::with_flags(flags)]
}
/// New Notcurses, expects [NcNotcursesOptions].
pub fn with_options(options: NcNotcursesOptions) -> NcResult<Self> {
raw_wrap![NcNotcurses::with_options(options)]
}
/// New Notcurses, expects [NcLogLevel] and flags.
pub fn with_debug(loglevel: NcLogLevel, flags: u64) -> NcResult<Self> {
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<NcBlitter> {
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<NcScale> {
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()
}
}

View File

@ -1,12 +1,12 @@
//! `NcPalette` methods and associated functions. //! `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 { impl NcPalette {
/// New NcPalette. /// New NcPalette.
/// ///
/// *C style function: [palette256_new()][crate::palette256_new].* /// *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) } unsafe { &mut *crate::palette256_new(nc) }
} }
@ -22,7 +22,7 @@ impl NcPalette {
/// Attempts to configure the terminal with this NcPalette. /// Attempts to configure the terminal with this NcPalette.
/// ///
/// *C style function: [palette256_use()][crate::palette256_use].* /// *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) }] error![unsafe { crate::palette256_use(nc, self) }]
} }

View File

@ -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. /// Helper function for a new NcPlane on C style tests.
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) unsafe fn ncplane_new_test<'a>( pub(crate) unsafe fn ncplane_new_test<'a>(
nc: &mut Notcurses, nc: &mut NcNotcurses,
y: NcOffset, y: NcOffset,
x: NcOffset, x: NcOffset,
rows: NcDimension, rows: NcDimension,

View File

@ -4,9 +4,9 @@ use core::ptr::{null, null_mut};
use crate::{ use crate::{
cstring, error, error_ref, error_ref_mut, rstring, NcAlign, NcAlphaBits, NcBoxMask, NcCell, cstring, error, error_ref, error_ref_mut, rstring, NcAlign, NcAlphaBits, NcBoxMask, NcCell,
NcChannel, NcChannelPair, NcColor, NcDimension, NcEgc, NcError, NcFadeCb, NcOffset, NcChannel, NcChannelPair, NcColor, NcDimension, NcEgc, NcError, NcFadeCb, NcNotcurses,
NcPaletteIndex, NcPlane, NcPlaneOptions, NcResizeCb, NcResult, NcRgb, NcStyleMask, NcTime, NcOffset, NcPaletteIndex, NcPlane, NcPlaneOptions, NcResizeCb, NcResult, NcRgb, NcStyleMask,
Notcurses, NCRESULT_ERR, NcTime, NCRESULT_ERR,
}; };
/// # NcPlaneOptions Constructors /// # NcPlaneOptions Constructors
@ -76,7 +76,7 @@ impl NcPlane {
/// ///
/// *C style function: [ncpile_create()][crate::ncpile_create].* /// *C style function: [ncpile_create()][crate::ncpile_create].*
pub fn new<'a>( pub fn new<'a>(
nc: &mut Notcurses, nc: &mut NcNotcurses,
y: NcOffset, y: NcOffset,
x: NcOffset, x: NcOffset,
rows: NcDimension, rows: NcDimension,
@ -91,12 +91,12 @@ impl NcPlane {
/// ///
/// *C style function: [ncpile_create()][crate::ncpile_create].* /// *C style function: [ncpile_create()][crate::ncpile_create].*
pub fn with_options<'a>( pub fn with_options<'a>(
nc: &mut Notcurses, nc: &mut NcNotcurses,
options: NcPlaneOptions, options: NcPlaneOptions,
) -> NcResult<&'a mut NcPlane> { ) -> NcResult<&'a mut NcPlane> {
error_ref_mut![ error_ref_mut![
unsafe { crate::ncpile_create(nc, &options) }, 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. /// The returned plane will be the top, bottom, and root of this new pile.
/// ///
/// *(No equivalent C style function)* /// *(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); let (trows, tcols) = crate::notcurses_term_dim_yx(nc);
assert![(trows > 0) & (tcols > 0)]; assert![(trows > 0) & (tcols > 0)];
Self::with_options( Self::with_options(
@ -310,7 +310,7 @@ impl NcPlane {
/// the provided values will be interpreted in some lossy fashion. /// the provided values will be interpreted in some lossy fashion.
/// ///
/// "HP-like" terminals require setting foreground and background at the same /// "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].* /// *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) { 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. /// the provided values will be interpreted in some lossy fashion.
/// ///
/// "HP-like" terminals require setting foreground and background at the same /// "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].* /// *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) { pub fn set_bg_rgb8(&mut self, red: NcColor, green: NcColor, blue: NcColor) {
@ -551,8 +551,10 @@ impl NcPlane {
if egc.is_null() { if egc.is_null() {
return Err(NcError::with_msg( return Err(NcError::with_msg(
NCRESULT_ERR, NCRESULT_ERR,
&format!("NcPlane.at_yx({}, {}, {:0X}, {:0X})", &format!(
y, x, stylemask, channels), "NcPlane.at_yx({}, {}, {:0X}, {:0X})",
y, x, stylemask, channels
),
)); ));
} }
let egc = core::char::from_u32(unsafe { *egc } as u32).expect("wrong char"); 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 { impl NcPlane {
/// Duplicates this NcPlane. /// Duplicates this NcPlane.
/// ///
@ -938,20 +940,14 @@ impl NcPlane {
/// ///
/// *C style function: [ncplane_above()][crate::ncplane_above].* /// *C style function: [ncplane_above()][crate::ncplane_above].*
pub fn above<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> { pub fn above<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> {
error_ref_mut![ error_ref_mut![unsafe { crate::ncplane_above(self) }, "NcPlane.above()"]
unsafe { crate::ncplane_above(self) },
"NcPlane.above()"
]
} }
/// Returns the NcPlane below this one, or None if already at the bottom. /// Returns the NcPlane below this one, or None if already at the bottom.
/// ///
/// *C style function: [ncplane_below()][crate::ncplane_below].* /// *C style function: [ncplane_below()][crate::ncplane_below].*
pub fn below<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> { pub fn below<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> {
error_ref_mut![ error_ref_mut![unsafe { crate::ncplane_below(self) }, "NcPlane.below()"]
unsafe { crate::ncplane_below(self) },
"NcPlane.below()"
]
} }
/// Relocates this NcPlane above the `above` NcPlane, in the z-buffer. /// Relocates this NcPlane above the `above` NcPlane, in the z-buffer.
@ -1004,7 +1000,8 @@ impl NcPlane {
target_x: NcDimension, target_x: NcDimension,
) -> NcResult<()> { ) -> NcResult<()> {
error![ error![
unsafe { crate::ncplane_mergedown( unsafe {
crate::ncplane_mergedown(
source, source,
self, self,
source_y as i32, source_y as i32,
@ -1013,9 +1010,12 @@ impl NcPlane {
len_x as i32, len_x as i32,
target_y as i32, target_y as i32,
target_x as i32, target_x as i32,
)}, )
&format!("NcPlane.mergedown(NcPlane, {}, {}, {}, {}, {}, {})", },
source_y, source_x, len_y, len_x, target_y, target_x) &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. // TODO: CHECK: what happens when it's bound to itself.
pub fn parent<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> { pub fn parent<'a>(&'a mut self) -> NcResult<&'a mut NcPlane> {
error_ref_mut![ error_ref_mut![unsafe { crate::ncplane_parent(self) }, "NcPlane.parent()"]
unsafe { crate::ncplane_parent(self) },
"NcPlane.parent()"
]
} }
/// Gets the parent to which this NcPlane is bound, if any. /// 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].* /// *C style function: [ncpile_rasterize()][crate::ncpile_rasterize].*
pub fn rasterize<'a>(&mut self) -> NcResult<()> { 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. /// Renders the pile of which this NcPlane is a part.
@ -1116,20 +1116,20 @@ impl NcPlane {
error![unsafe { crate::ncpile_render(self) }, "NcPlane.render()"] 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].* /// *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![ error_ref_mut![
unsafe { crate::ncplane_notcurses(self) }, unsafe { crate::ncplane_notcurses(self) },
"NcPlane.notcurses()" "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].* /// *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![ error_ref![
unsafe { crate::ncplane_notcurses_const(self) }, unsafe { crate::ncplane_notcurses_const(self) },
"NcPlane.notcurses()" "NcPlane.notcurses()"
@ -1339,7 +1339,8 @@ impl NcPlane {
x_len: NcDimension, x_len: NcDimension,
) -> NcResult<()> { ) -> NcResult<()> {
error![ error![
unsafe { crate::ncplane_resize( unsafe {
crate::ncplane_resize(
self, self,
keep_y as i32, keep_y as i32,
keep_x as i32, keep_x as i32,
@ -1349,9 +1350,12 @@ impl NcPlane {
x_off as i32, x_off as i32,
y_len as i32, y_len as i32,
x_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) &format!(
"NcPlane.resize({}, {}, {}, {}, {}, {}, {}, {})",
keep_y, keep_x, keep_len_y, keep_len_x, y_off, x_off, y_len, x_len
)
] ]
} }

View File

@ -1,6 +1,6 @@
//! `NcStats` //! `NcStats`
use crate::Notcurses; use crate::NcNotcurses;
/// notcurses runtime statistics /// notcurses runtime statistics
pub type NcStats = crate::bindings::ffi::ncstats; pub type NcStats = crate::bindings::ffi::ncstats;
@ -8,17 +8,17 @@ pub type NcStats = crate::bindings::ffi::ncstats;
/// # `NcStats` Methods. /// # `NcStats` Methods.
impl NcStats { impl NcStats {
/// Allocates an NcStats object. /// 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) } unsafe { &mut *crate::notcurses_stats_alloc(nc) }
} }
/// Acquires an atomic snapshot of the Notcurses object's stats. /// Acquires an atomic snapshot of the NcNotcurses object's stats.
pub fn stats(&mut self, nc: &Notcurses) { pub fn stats(&mut self, nc: &NcNotcurses) {
unsafe { crate::notcurses_stats(nc, self) } unsafe { crate::notcurses_stats(nc, self) }
} }
/// Resets all cumulative stats (immediate ones are not reset). /// 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) } unsafe { crate::notcurses_stats_reset(nc, self) }
} }
} }