|
| 1 | +use std::time::Duration; |
| 2 | + |
1 | 3 | use aho_corasick::AhoCorasick; |
2 | 4 | use miette::Context; |
3 | 5 | use miette::IntoDiagnostic; |
@@ -98,6 +100,42 @@ impl GhciStdout { |
98 | 100 | Ok(()) |
99 | 101 | } |
100 | 102 |
|
| 103 | + /// Read any immediately-available output from the pipe, then drain stale prompts from |
| 104 | + /// the internal buffer. Returns the number of prompts found and discarded. |
| 105 | + #[expect(unused)] |
| 106 | + pub async fn buffer_and_drain_prompts(&mut self, timeout: Duration) -> miette::Result<usize> { |
| 107 | + self.reader |
| 108 | + .buffer_available(&mut self.buffer, timeout, WriteBehavior::NoFinalLine) |
| 109 | + .await?; |
| 110 | + |
| 111 | + self.reader |
| 112 | + .drain_buffered_chunks(&ReadOpts { |
| 113 | + end_marker: &self.prompt_patterns, |
| 114 | + find: FindAt::Anywhere, |
| 115 | + writing: WriteBehavior::NoFinalLine, |
| 116 | + buffer: &mut self.buffer, |
| 117 | + }) |
| 118 | + .await |
| 119 | + } |
| 120 | + |
| 121 | + /// Read stdout until the given marker string is found, discarding everything before it. |
| 122 | + /// |
| 123 | + /// Used by `send_sigint` to synchronize with GHCi after an interrupt: a sync expression |
| 124 | + /// is sent on stdin and this method reads until its output appears, guaranteeing that all |
| 125 | + /// prior output has been consumed. |
| 126 | + #[expect(unused)] |
| 127 | + pub async fn read_until_marker(&mut self, marker: &str) -> miette::Result<String> { |
| 128 | + let pattern = AhoCorasick::from_anchored_patterns([marker]); |
| 129 | + self.reader |
| 130 | + .read_until(&mut ReadOpts { |
| 131 | + end_marker: &pattern, |
| 132 | + find: FindAt::Anywhere, |
| 133 | + writing: WriteBehavior::NoFinalLine, |
| 134 | + buffer: &mut self.buffer, |
| 135 | + }) |
| 136 | + .await |
| 137 | + } |
| 138 | + |
101 | 139 | #[instrument(skip_all, level = "debug")] |
102 | 140 | pub async fn show_paths(&mut self) -> miette::Result<ShowPaths> { |
103 | 141 | let lines = self |
|
0 commit comments