Skip to content

Commit 3d22411

Browse files
committed
cmdutils: Add helper to run and parse JSON
It's handy to have a central helper for this. Signed-off-by: Colin Walters <[email protected]>
1 parent 4ac9079 commit 3d22411

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

lib/src/cmdutils.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ use std::{
33
process::Command,
44
};
55

6-
use anyhow::Result;
6+
use anyhow::{Context, Result};
77

88
/// Helpers intended for [`std::process::Command`].
99
pub(crate) trait CommandRunExt {
1010
fn run(&mut self) -> Result<()>;
11+
/// Execute the child process, parsing its stdout as JSON.
12+
fn run_and_parse_json<T: serde::de::DeserializeOwned>(&mut self) -> Result<T>;
1113
}
1214

1315
/// Helpers intended for [`std::process::ExitStatus`].
@@ -68,6 +70,15 @@ impl CommandRunExt for Command {
6870
self.stderr(stderr.try_clone()?);
6971
self.status()?.check_status(stderr)
7072
}
73+
74+
fn run_and_parse_json<T: serde::de::DeserializeOwned>(&mut self) -> Result<T> {
75+
let mut stdout = tempfile::tempfile()?;
76+
self.stdout(stdout.try_clone()?);
77+
self.run()?;
78+
stdout.seek(std::io::SeekFrom::Start(0)).context("seek")?;
79+
let stdout = std::io::BufReader::new(stdout);
80+
serde_json::from_reader(stdout).map_err(Into::into)
81+
}
7182
}
7283

7384
/// Helpers intended for [`tokio::process::Command`].
@@ -118,6 +129,21 @@ fn command_run_ext() {
118129
);
119130
}
120131

132+
#[test]
133+
fn command_run_ext_json() {
134+
#[derive(serde::Deserialize)]
135+
struct Foo {
136+
a: String,
137+
b: u32,
138+
}
139+
let v: Foo = Command::new("echo")
140+
.arg(r##"{"a": "somevalue", "b": 42}"##)
141+
.run_and_parse_json()
142+
.unwrap();
143+
assert_eq!(v.a, "somevalue");
144+
assert_eq!(v.b, 42);
145+
}
146+
121147
#[tokio::test]
122148
async fn async_command_run_ext() {
123149
use tokio::process::Command as AsyncCommand;

0 commit comments

Comments
 (0)