use std::io::{Read, Write};
use crate::config::PartialConfig;
use crate::ingress::IngressId;
use crate::pipeline::RawSink;
use super::super::events::fail_inband;
use super::super::raw::read_to_vec;
use super::super::{drive, generate};
use super::{edge, prepare, reject_replay, turn, Host, MasqIn, Respond};
pub(crate) fn filter(
dialect: IngressId,
reader: &mut dyn Read,
merged: PartialConfig,
raw_out: bool,
stdout: &mut dyn Write,
host: &Host,
) -> u8 {
let cx = MasqIn {
dialect,
reject: reject_replay(merged.ingress.as_ref()),
merged,
stash: host.stash,
cache: host.cache,
};
let body = match read_to_vec(reader) {
Ok(bytes) => bytes,
Err(e) => {
if raw_out {
return fail_inband(&mut RawSink::new(stdout), e);
}
return edge(dialect, e, host.clock, &mut StdoutRespond { w: stdout });
}
};
if raw_out {
let mut sink = RawSink::new(stdout);
return match prepare(cx, &body) {
Ok((req, cfg, _)) => drive::drive(
generate::send_encoded(req, cfg, host),
true,
&mut sink,
host.clock.now(),
),
Err(e) => fail_inband(&mut sink, e),
};
}
turn(cx, &body, host, &mut StdoutRespond { w: stdout })
}
struct StdoutRespond<'a> {
w: &'a mut dyn Write,
}
impl Respond for StdoutRespond<'_> {
fn begin(&mut self, _status: u16, _sse: bool) -> std::io::Result<()> {
Ok(())
}
fn chunk(&mut self, bytes: &[u8]) -> std::io::Result<()> {
self.w.write_all(bytes).and_then(|()| self.w.flush())
}
fn end(&mut self) -> std::io::Result<()> {
self.w.flush()
}
}