Skip to content

Commit 165fe96

Browse files
committedJan 1, 2025··
feat: decouple public API from dependencies
1 parent dd1430a commit 165fe96

File tree

1 file changed

+75
-21
lines changed

1 file changed

+75
-21
lines changed
 

‎src/lib.rs

+75-21
Original file line numberDiff line numberDiff line change
@@ -683,34 +683,85 @@ pub fn is_windows_10() -> bool {
683683
#[derive(Debug, Error)]
684684
pub enum Error {
685685
/// Any I/O error.
686-
#[error(transparent)]
686+
#[error("io: {0}")]
687687
Io(#[from] io::Error),
688688

689689
/// A non-success exit status from a command.
690-
#[error("{0}: {1}")]
690+
#[error("command: {0}: {1}")]
691691
Command(&'static str, ExitStatus),
692692

693693
/// Any nix (libc) error.
694694
#[cfg(unix)]
695-
#[error(transparent)]
696-
Nix(#[from] nix::Error),
695+
#[error("unix: {0}")]
696+
Nix(#[from] NixError),
697697

698698
/// Any terminfo error.
699-
#[error(transparent)]
700-
Terminfo(#[from] terminfo::Error),
699+
#[error("terminfo: {0}")]
700+
Terminfo(#[from] TerminfoError),
701701

702702
/// A missing terminfo capability.
703-
#[error("required terminfo capability not available: {0}")]
703+
#[error("terminfo: capability not available: {0}")]
704704
TerminfoCap(&'static str),
705705

706706
/// A null-pointer error.
707-
#[error("encountered a null pointer while reading {0}")]
707+
#[error("ffi: encountered a null pointer while reading {0}")]
708708
NullPtr(&'static str),
709709
}
710710

711+
/// Nix error type.
712+
///
713+
/// This wraps a [`nix::Error`] to avoid directly exposing the type in the public API, which
714+
/// required a breaking change every time `clearscreen` updated its `nix` version.
715+
///
716+
/// To obtain a nix error, convert this error to an `i32` then use [`nix::Error::from_raw`]:
717+
///
718+
/// Creating a [`NixError`] is explicitly not possible from the public API.
719+
///
720+
/// ```no_compile
721+
/// let nix_error = nix::Error::from_raw(error.into());
722+
/// assert_eq!(nix_error, nix::Error::EINVAL);
723+
/// ```
724+
#[cfg(unix)]
725+
#[derive(Debug, Error)]
726+
#[error(transparent)]
727+
pub struct NixError(nix::Error);
728+
729+
#[cfg(unix)]
730+
impl From<NixError> for i32 {
731+
fn from(err: NixError) -> Self {
732+
err.0 as _
733+
}
734+
}
735+
736+
/// Terminfo error type.
737+
///
738+
/// This wraps a [`terminfo::Error`] to avoid directly exposing the type in the public API, which
739+
/// required a breaking change every time `clearscreen` updated its `terminfo` version.
740+
#[derive(Debug, Error)]
741+
#[error("{description}")]
742+
pub struct TerminfoError {
743+
inner: terminfo::Error,
744+
description: String,
745+
}
746+
747+
impl From<terminfo::Error> for TerminfoError {
748+
fn from(inner: terminfo::Error) -> Self {
749+
Self {
750+
description: inner.to_string(),
751+
inner,
752+
}
753+
}
754+
}
755+
756+
impl From<terminfo::Error> for Error {
757+
fn from(err: terminfo::Error) -> Self {
758+
Self::Terminfo(TerminfoError::from(err))
759+
}
760+
}
761+
711762
#[cfg(unix)]
712763
mod unix {
713-
use super::Error;
764+
use super::{Error, NixError};
714765

715766
use nix::{
716767
sys::termios::{
@@ -726,8 +777,10 @@ mod unix {
726777
write_termios(|t| {
727778
t.input_flags.insert(
728779
InputFlags::BRKINT
729-
| InputFlags::ICRNL | InputFlags::IGNPAR
730-
| InputFlags::ISTRIP | InputFlags::IXON,
780+
| InputFlags::ICRNL
781+
| InputFlags::IGNPAR
782+
| InputFlags::ISTRIP
783+
| InputFlags::IXON,
731784
);
732785
t.output_flags.insert(OutputFlags::OPOST);
733786
t.local_flags.insert(LocalFlags::ICANON | LocalFlags::ISIG);
@@ -736,11 +789,12 @@ mod unix {
736789

737790
pub(crate) fn vt_well_done() -> Result<(), Error> {
738791
write_termios(|t| {
739-
let mut inserts =
740-
InputFlags::BRKINT
741-
| InputFlags::ICRNL | InputFlags::IGNPAR
742-
| InputFlags::IMAXBEL
743-
| InputFlags::ISTRIP | InputFlags::IXON;
792+
let mut inserts = InputFlags::BRKINT
793+
| InputFlags::ICRNL
794+
| InputFlags::IGNPAR
795+
| InputFlags::IMAXBEL
796+
| InputFlags::ISTRIP
797+
| InputFlags::IXON;
744798

745799
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
746800
{
@@ -763,19 +817,19 @@ mod unix {
763817
}
764818

765819
fn write_termios(f: impl Fn(&mut Termios)) -> Result<(), Error> {
766-
if isatty(stdin().as_raw_fd())? {
767-
let mut t = tcgetattr(stdin().as_fd())?;
820+
if isatty(stdin().as_raw_fd()).map_err(NixError)? {
821+
let mut t = tcgetattr(stdin().as_fd()).map_err(NixError)?;
768822
reset_termios(&mut t);
769823
f(&mut t);
770-
tcsetattr(stdin().as_fd(), TCSANOW, &t)?;
824+
tcsetattr(stdin().as_fd(), TCSANOW, &t).map_err(NixError)?;
771825
} else {
772826
let tty = OpenOptions::new().read(true).write(true).open("/dev/tty")?;
773827
let fd = tty.as_fd();
774828

775-
let mut t = tcgetattr(fd)?;
829+
let mut t = tcgetattr(fd).map_err(NixError)?;
776830
reset_termios(&mut t);
777831
f(&mut t);
778-
tcsetattr(fd, TCSANOW, &t)?;
832+
tcsetattr(fd, TCSANOW, &t).map_err(NixError)?;
779833
}
780834

781835
Ok(())

0 commit comments

Comments
 (0)
Please sign in to comment.