Skip to content

Commit 94e31c9

Browse files
committed
impl Try for ExitStatus
Currently just sys/unix is implemented.
1 parent b862b43 commit 94e31c9

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@
300300
#![feature(thin_box)]
301301
#![feature(toowned_clone_into)]
302302
#![feature(try_reserve_kind)]
303+
#![feature(try_trait_v2)]
303304
#![feature(vec_into_raw_parts)]
304305
//
305306
// Library features (unwind):

library/std/src/process.rs

+28
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,12 @@ use crate::fmt;
112112
use crate::fs;
113113
use crate::io::{self, IoSlice, IoSliceMut};
114114
use crate::num::NonZeroI32;
115+
use crate::ops::{ControlFlow, FromResidual, Try};
115116
use crate::path::Path;
116117
use crate::str;
117118
use crate::sys::pipe::{read2, AnonPipe};
118119
use crate::sys::process as imp;
120+
119121
#[stable(feature = "command_access", since = "1.57.0")]
120122
pub use crate::sys_common::process::CommandEnvs;
121123
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
@@ -1542,6 +1544,29 @@ impl fmt::Display for ExitStatus {
15421544
}
15431545
}
15441546

1547+
#[unstable(feature = "exit_status_error", issue = "84908")]
1548+
impl Try for ExitStatus {
1549+
type Output = ();
1550+
type Residual = Result<Infallible, ExitStatusError>;
1551+
1552+
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
1553+
self.0.try_branch()
1554+
}
1555+
1556+
fn from_output((): ()) -> Self {
1557+
Self(imp::ExitStatus::zero_status())
1558+
}
1559+
}
1560+
1561+
#[unstable(feature = "exit_status_error", issue = "84908")]
1562+
impl FromResidual<Result<Infallible, ExitStatusError>> for ExitStatus {
1563+
fn from_residual(residual: Result<Infallible, ExitStatusError>) -> Self {
1564+
match residual {
1565+
Err(exit_status_error) => exit_status_error.into(),
1566+
}
1567+
}
1568+
}
1569+
15451570
/// Allows extension traits within `std`.
15461571
#[unstable(feature = "sealed", issue = "none")]
15471572
impl crate::sealed::Sealed for ExitStatusError {}
@@ -1574,6 +1599,9 @@ pub struct ExitStatusError(imp::ExitStatusError);
15741599

15751600
#[unstable(feature = "exit_status_error", issue = "84908")]
15761601
impl ExitStatusError {
1602+
pub(crate) fn new(exit_status_error: imp::ExitStatusError) -> Self {
1603+
ExitStatusError(exit_status_error)
1604+
}
15771605
/// Reports the exit code, if applicable, from an `ExitStatusError`.
15781606
///
15791607
/// In Unix terms the return value is the **exit status**: the value passed to `exit`, if the

library/std/src/sys/unix/process/process_unix.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use crate::convert::Infallible;
12
use crate::fmt;
23
use crate::io::{self, Error, ErrorKind};
34
use crate::mem;
45
use crate::num::NonZeroI32;
6+
use crate::ops::ControlFlow;
57
use crate::ptr;
68
use crate::sys;
79
use crate::sys::cvt;
@@ -647,6 +649,12 @@ impl ExitStatus {
647649
ExitStatus(status)
648650
}
649651

652+
// Returns a new 0 status, to avoid hard coding zero
653+
// in crate::process::ExitStatus.
654+
pub fn zero_status() -> ExitStatus {
655+
ExitStatus(0)
656+
}
657+
650658
fn exited(&self) -> bool {
651659
libc::WIFEXITED(self.0)
652660
}
@@ -663,6 +671,17 @@ impl ExitStatus {
663671
}
664672
}
665673

674+
pub fn try_branch(
675+
self,
676+
) -> ControlFlow<Result<Infallible, crate::process::ExitStatusError>, ()> {
677+
match NonZero_c_int::try_from(self.0) {
678+
Ok(failure) => ControlFlow::Break(Err(crate::process::ExitStatusError::new(
679+
ExitStatusError(failure),
680+
))),
681+
Err(_) => ControlFlow::Continue(()),
682+
}
683+
}
684+
666685
pub fn code(&self) -> Option<i32> {
667686
self.exited().then(|| libc::WEXITSTATUS(self.0))
668687
}

0 commit comments

Comments
 (0)