diff --git a/rust/src/lib.rs b/rust/src/lib.rs index a6e72bc30..80dd286f6 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,12 +1,98 @@ -//! `libnotcurses-sys` is an unsafe Rust wrapper for the notcurses C library +//! `libnotcurses-sys` is a *close to the metal* Rust wrapper for the [notcurses +//! C library](https://www.github.com/dankamongmen/notcurses/) //! -//! The API is mostly the original one, while following the Rust API Guidelines. +//! There is also the [notcurses](https://crates.io/crates/notcurses) crate, +//! for a more idiomatic wrapper, which should be safer and more higher level. //! -//! For a safer wrapper with a more idiomatic API for Rust, you can use -//! [](https://crates.io/crates/notcurses) -//! [notcurses-rs](https://github.com/dankamongmen/notcurses-rs) +//! # Ways of using this library //! -//! ### notcurses C API docs: +//! The *rusty* way is to use the provided methods and constructors: +//! ```rust +//! use libnotcurses_sys::*; +//! +//! fn main() { +//! let nc = Notcurses::without_altscreen(); +//! let plane = nc.stdplane(); +//! plane.putstr("hello world"); +//! nc.render(); +//! nc.stop(); +//! } +//! ``` +//! +//! You can also use the C API functions directly over the constructed types. +//! +//! 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. +//! +//! There are plans to manually wrap all the C API functions, in order to +//! achieve better ergonomics and consistent syntax. +//! ```rust +//! use libnotcurses_sys::*; +//! +//! fn main() { +//! let options = NotcursesOptions::with_flags(NCOPTION_NO_ALTERNATE_SCREEN); +//! let nc = Notcurses::with_options(&options); +//! unsafe { +//! let plane = notcurses_stdplane(nc); +//! ncplane_putstr(&mut *plane, "hello world"); +//! notcurses_render(nc); +//! notcurses_stop(nc); +//! } +//! } +//! ``` +//! +//! 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::*; +//! +//! fn main() { +//! let options = ffi::notcurses_options { +//! termtype: null(), +//! renderfp: null_mut(), +//! loglevel: 0, +//! margin_t: 0, +//! margin_r: 0, +//! margin_b: 0, +//! margin_l: 0, +//! flags: NCOPTION_NO_ALTERNATE_SCREEN, +//! }; +//! unsafe { +//! let nc = notcurses_init(&options, null_mut()); +//! let plane = notcurses_stdplane(nc); +//! ncplane_putstr(&mut *plane, "hello world"); +//! notcurses_stop(nc); +//! } +//! } +//! +//! ``` +//! ## Limitations of this library +//! +//! There are several common patterns in Rust that this library doesn't employ, +//! and focuses instead on remaining at a very close distance to the C API. +//! +//! 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. Instead of handling errors with `Result` (as is customary in Rust), +//! several functions return an [NcResult] with a value of [NCRESULT_ERR], +//! (as is customary in C), or [NCRESULT_OK]. +//! +//! The [notcurses]() crate overcomes this limitations by using higher level +//! abstractions, while pulling itself apart from the C API, in ways this +//! library can not do. +//! +//! ### Things this library does do +//! +//! - Type aliases every underlying C type to leverage type checking. +//! - Renames types to enforce regularity and consistency. (e.g. [NcCell]) +//! - Has handy macros like [sleep], [rsleep] & [cstring]. +//! +//! ## notcurses C API docs: //! //! - [Doxygen Documentation](https://nick-black.com/notcurses/html/index.html) //! - [API reference (man pages)](https://nick-black.com/notcurses/)