1use orfail::OrFail;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use std::io::Write;
5
6pub type Object = serde_json::Map<String, Value>;
7
8pub fn from_stdin<T>() -> impl Iterator<Item = orfail::Result<T>>
9where
10 T: for<'a> Deserialize<'a>,
11{
12 let stdin = std::io::stdin();
13 let stdin = stdin.lock();
14 serde_json::Deserializer::from_reader(stdin)
15 .into_iter()
16 .map(|result| result.or_fail())
17}
18
19pub fn to_stdout(
20 values: impl Iterator<Item = orfail::Result<impl Serialize>>,
21) -> orfail::Result<()> {
22 let stdout = std::io::stdout();
23 let mut stdout = stdout.lock();
24 for value in values {
25 let value = value.or_fail()?;
26 let json = serde_json::to_string(&value).or_fail()?;
27 if ignore_broken_pipe(writeln!(&mut stdout, "{}", json)).or_fail()? {
28 break;
29 }
30 }
31 Ok(())
32}
33
34fn ignore_broken_pipe(result: std::io::Result<()>) -> std::io::Result<bool> {
35 match result {
36 Ok(()) => Ok(false),
37 Err(err) if err.kind() == std::io::ErrorKind::BrokenPipe => Ok(true),
38 Err(err) => Err(err),
39 }
40}