1use std::{
2 cell::RefCell,
3 process::{Child, ChildStdin, ChildStdout, Command, Stdio},
4};
5
6use anyhow::{anyhow, Result};
7
8use crate::RwBuilder;
9
10#[derive(Debug)]
14pub struct Builder {
15 command: RefCell<Command>,
18}
19
20impl Builder {
21 #[must_use]
24 pub fn new(command: Command) -> Self {
25 Self { command: command.into() }
26 }
27
28 pub fn spawn(&self) -> Result<ChildBuilder> {
35 let child =
36 self.command.borrow_mut().stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
37 Ok(ChildBuilder { child: child.into() })
38 }
39}
40
41impl RwBuilder for Builder {
42 type Reader = ChildStdout;
43 type Writer = ChildStdin;
44
45 fn reader(&self) -> Result<Self::Reader> {
46 let mut child = self.command.borrow_mut().stdout(Stdio::piped()).spawn()?;
47 child.stdout.take().ok_or_else(|| anyhow!("no child stdout"))
48 }
49
50 fn writer(&self) -> Result<Self::Writer> {
51 let mut child = self.command.borrow_mut().stdin(Stdio::piped()).spawn()?;
52 child.stdin.take().ok_or_else(|| anyhow!("no child stdin"))
53 }
54}
55
56#[derive(Debug)]
60pub struct ChildBuilder {
61 child: RefCell<Child>,
63}
64
65impl RwBuilder for ChildBuilder {
66 type Reader = ChildStdout;
67 type Writer = ChildStdin;
68
69 fn reader(&self) -> Result<Self::Reader> {
70 self.child
71 .borrow_mut()
72 .stdout
73 .take()
74 .ok_or_else(|| anyhow!("No child stdout. Did you already build a reader?"))
75 }
76
77 fn writer(&self) -> Result<Self::Writer> {
78 self.child
79 .borrow_mut()
80 .stdin
81 .take()
82 .ok_or_else(|| anyhow!("No child stdin. Did you already build a writer?"))
83 }
84}