Skip to content

Commit 097a66f

Browse files
committed
Initial commit.
0 parents  commit 097a66f

File tree

19 files changed

+1679
-0
lines changed

19 files changed

+1679
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

Cargo.lock

Lines changed: 119 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[package]
2+
name = "proc-result"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[lints.clippy]
7+
pedantic = "deny"
8+
9+
[features]
10+
std = []
11+
default = ["std"]
12+
serde = ["serde/derive"]
13+
14+
[dependencies]
15+
serde = { version = "1.0.219", features = ["derive"], optional = true }
16+
17+
[dependencies.num-traits]
18+
version = "0.2.19"
19+
default-features = false
20+
21+
[dev-dependencies]
22+
libc = "0.2.172"
23+
serde_json = "1.0.140"

LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2025 Matan Lurey
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# proc-result
2+
3+
A tiny cross-platform library containing exit status and code types.
4+
5+
Unlike `std::process`, this crate does not require the standard library[^1], nor
6+
`libc`, and can create and interpret exit codes of non-current platforms. For
7+
example, on Windows, it can read and interpret exit codes that may have been
8+
recorded from a Linux process, or vice versa.
9+
10+
[^1]: The `std` feature is enabled by default, but can be disabled.
11+
12+
## Usage
13+
14+
Most users of the crate will use the `ToProcResult` trait, which converts the
15+
result a run of a subprocess to a `ProcResult`, either a successful or an error
16+
explaining what exit code or (on Unix platforms) the signal the subprocess was
17+
prematurely terminated with, and is constructed from a
18+
`std::process::ExitStatus`:
19+
20+
```rust
21+
use proc_result::ToProcResult;
22+
use std::error::Error;
23+
use std::process::Command;
24+
25+
fn main() -> Result<(), Box<dyn Error>> {
26+
let result = Command::new("ls").status()?.to_proc_result()?;
27+
Ok(())
28+
}
29+
```
30+
31+
Advanced users, or users writing tests or interpreting exit codes from other
32+
platforms may import and use the platform-specific exit code types directly,
33+
from the `unix` or `windows` modules, respectively. For example, to create a
34+
Unix exit code from a raw integer:
35+
36+
```rust
37+
use proc_result::unix::ExitCode;
38+
39+
fn main() {
40+
let code = ExitCode::from_raw(1);
41+
if code.is_success() {
42+
println!("Command succeeded!");
43+
} else {
44+
eprintln!("Command failed with exit code: {}", code);
45+
}
46+
}
47+
```
48+
49+
## Features
50+
51+
Name | Default | Description
52+
------- | ------- | -----------
53+
`serde` | `false` | Enables serialization support for most types using `serde`.
54+
`std` | `true` | Enables compatibility with `std::process::ExitStatus`.

examples/exit_code_0.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exit 0

examples/exit_code_1.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exit 1

examples/failure.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use proc_result::ToProcResult;
2+
3+
fn main() -> Result<(), Box<dyn std::error::Error>> {
4+
std::process::Command::new("examples/exit_code_1.sh")
5+
.status()?
6+
.to_proc_result()?;
7+
Ok(())
8+
}

examples/hang_forever.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
3+
# Hangs forever, requiring CTRL-C to terminate.
4+
5+
while true; do
6+
sleep 1
7+
done

examples/signal.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use proc_result::ToProcResult;
2+
3+
fn main() -> Result<(), Box<dyn std::error::Error>> {
4+
let mut child = std::process::Command::new("examples/hang_forever.sh").spawn()?;
5+
let pid = child.id();
6+
7+
// Spawn a thread, and in 1s, use the PID to kill the process (not the child handle).
8+
std::thread::spawn(move || {
9+
std::thread::sleep(std::time::Duration::from_secs(1));
10+
println!("Using SIGTERM to kill process {pid}");
11+
let _ = std::process::Command::new("kill")
12+
.arg("-9")
13+
.arg(pid.to_string())
14+
.status();
15+
println!("Done");
16+
});
17+
18+
println!("Waiting for process to end");
19+
child.wait()?.to_proc_result()?;
20+
21+
println!("Done!");
22+
Ok(())
23+
}

0 commit comments

Comments
 (0)