@@ -683,34 +683,85 @@ pub fn is_windows_10() -> bool {
683
683
#[ derive( Debug , Error ) ]
684
684
pub enum Error {
685
685
/// Any I/O error.
686
- #[ error( transparent ) ]
686
+ #[ error( "io: {0}" ) ]
687
687
Io ( #[ from] io:: Error ) ,
688
688
689
689
/// A non-success exit status from a command.
690
- #[ error( "{0}: {1}" ) ]
690
+ #[ error( "command: {0}: {1}" ) ]
691
691
Command ( & ' static str , ExitStatus ) ,
692
692
693
693
/// Any nix (libc) error.
694
694
#[ cfg( unix) ]
695
- #[ error( transparent ) ]
696
- Nix ( #[ from] nix :: Error ) ,
695
+ #[ error( "unix: {0}" ) ]
696
+ Nix ( #[ from] NixError ) ,
697
697
698
698
/// Any terminfo error.
699
- #[ error( transparent ) ]
700
- Terminfo ( #[ from] terminfo :: Error ) ,
699
+ #[ error( "terminfo: {0}" ) ]
700
+ Terminfo ( #[ from] TerminfoError ) ,
701
701
702
702
/// A missing terminfo capability.
703
- #[ error( "required terminfo capability not available: {0}" ) ]
703
+ #[ error( "terminfo: capability not available: {0}" ) ]
704
704
TerminfoCap ( & ' static str ) ,
705
705
706
706
/// A null-pointer error.
707
- #[ error( "encountered a null pointer while reading {0}" ) ]
707
+ #[ error( "ffi: encountered a null pointer while reading {0}" ) ]
708
708
NullPtr ( & ' static str ) ,
709
709
}
710
710
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
+
711
762
#[ cfg( unix) ]
712
763
mod unix {
713
- use super :: Error ;
764
+ use super :: { Error , NixError } ;
714
765
715
766
use nix:: {
716
767
sys:: termios:: {
@@ -726,8 +777,10 @@ mod unix {
726
777
write_termios ( |t| {
727
778
t. input_flags . insert (
728
779
InputFlags :: BRKINT
729
- | InputFlags :: ICRNL | InputFlags :: IGNPAR
730
- | InputFlags :: ISTRIP | InputFlags :: IXON ,
780
+ | InputFlags :: ICRNL
781
+ | InputFlags :: IGNPAR
782
+ | InputFlags :: ISTRIP
783
+ | InputFlags :: IXON ,
731
784
) ;
732
785
t. output_flags . insert ( OutputFlags :: OPOST ) ;
733
786
t. local_flags . insert ( LocalFlags :: ICANON | LocalFlags :: ISIG ) ;
@@ -736,11 +789,12 @@ mod unix {
736
789
737
790
pub ( crate ) fn vt_well_done ( ) -> Result < ( ) , Error > {
738
791
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 ;
744
798
745
799
#[ cfg( any( target_os = "android" , target_os = "linux" , target_os = "macos" ) ) ]
746
800
{
@@ -763,19 +817,19 @@ mod unix {
763
817
}
764
818
765
819
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 ) ?;
768
822
reset_termios ( & mut t) ;
769
823
f ( & mut t) ;
770
- tcsetattr ( stdin ( ) . as_fd ( ) , TCSANOW , & t) ?;
824
+ tcsetattr ( stdin ( ) . as_fd ( ) , TCSANOW , & t) . map_err ( NixError ) ?;
771
825
} else {
772
826
let tty = OpenOptions :: new ( ) . read ( true ) . write ( true ) . open ( "/dev/tty" ) ?;
773
827
let fd = tty. as_fd ( ) ;
774
828
775
- let mut t = tcgetattr ( fd) ?;
829
+ let mut t = tcgetattr ( fd) . map_err ( NixError ) ?;
776
830
reset_termios ( & mut t) ;
777
831
f ( & mut t) ;
778
- tcsetattr ( fd, TCSANOW , & t) ?;
832
+ tcsetattr ( fd, TCSANOW , & t) . map_err ( NixError ) ?;
779
833
}
780
834
781
835
Ok ( ( ) )
0 commit comments