1use std::{
2 cell::RefCell,
3 process::{Child, ChildStdin, ChildStdout, Command, Stdio},
4};
5
6use crate::{Error, Result};
7
8use crate::RwBuilder;
9
10#[derive(Debug)]
14#[must_use]
15pub struct Builder {
16 command: RefCell<Command>,
19}
20
21impl Builder {
22 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(Error::MissingChildStdout("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(Error::MissingChildStdin("no child stdin"))
53 }
54}
55
56#[derive(Debug)]
60#[must_use]
61pub struct ChildBuilder {
62 child: RefCell<Child>,
64}
65
66impl RwBuilder for ChildBuilder {
67 type Reader = ChildStdout;
68 type Writer = ChildStdin;
69
70 fn reader(&self) -> Result<Self::Reader> {
71 self.child
72 .borrow_mut()
73 .stdout
74 .take()
75 .ok_or(Error::MissingChildStdout("No child stdout. Did you already build a reader?"))
76 }
77
78 fn writer(&self) -> Result<Self::Writer> {
79 self.child
80 .borrow_mut()
81 .stdin
82 .take()
83 .ok_or(Error::MissingChildStdin("No child stdin. Did you already build a writer?"))
84 }
85}