ergot_base/interface_manager/utils/
framed_stream.rs1use bbq2::{prod_cons::framed::FramedProducer, traits::bbqhdl::BbqHandle};
7use postcard::ser_flavors;
8use serde::Serialize;
9
10use crate::{
11 AnyAllAppendix, FrameKind, ProtocolError,
12 interface_manager::InterfaceSink,
13 wire_frames::{self, CommonHeader},
14};
15
16pub struct Sink<Q>
17where
18 Q: BbqHandle,
19{
20 pub(crate) mtu: u16,
21 pub(crate) prod: FramedProducer<Q, u16>,
22}
23
24#[allow(clippy::result_unit_err)] impl<Q> Sink<Q>
26where
27 Q: BbqHandle,
28{
29 pub fn new_from_handle(q: Q, mtu: u16) -> Self {
30 Self {
31 mtu,
32 prod: q.framed_producer(),
33 }
34 }
35
36 pub const fn new(prod: FramedProducer<Q, u16>, mtu: u16) -> Self {
37 Self { mtu, prod }
38 }
39}
40
41impl<Q> InterfaceSink for Sink<Q>
42where
43 Q: BbqHandle,
44{
45 fn send_ty<T: Serialize>(
46 &mut self,
47 hdr: &CommonHeader,
48 apdx: Option<&AnyAllAppendix>,
49 body: &T,
50 ) -> Result<(), ()> {
51 let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR;
52
53 if is_err {
54 return Err(());
56 }
57 let mut wgr = self.prod.grant(self.mtu).map_err(drop)?;
58
59 let ser = ser_flavors::Slice::new(&mut wgr);
60 let used = wire_frames::encode_frame_ty(ser, hdr, apdx, body).map_err(drop)?;
61 let len = used.len() as u16;
62 wgr.commit(len);
63
64 Ok(())
65 }
66
67 fn send_raw(&mut self, hdr: &CommonHeader, hdr_raw: &[u8], body: &[u8]) -> Result<(), ()> {
68 let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR;
69
70 if is_err {
71 return Err(());
73 }
74 let len = hdr_raw.len() + body.len();
75 let Ok(len) = u16::try_from(len) else {
76 return Err(());
77 };
78 let mut wgr = self.prod.grant(len).map_err(drop)?;
79 let (ghdr, gbody) = wgr.split_at_mut(hdr_raw.len());
80 ghdr.copy_from_slice(hdr_raw);
81 gbody.copy_from_slice(body);
82
83 wgr.commit(len);
84
85 Ok(())
86 }
87
88 fn send_err(&mut self, hdr: &CommonHeader, err: ProtocolError) -> Result<(), ()> {
89 let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR;
90
91 if !is_err {
93 return Err(());
95 }
96 let mut wgr = self.prod.grant(self.mtu).map_err(drop)?;
97
98 let ser = ser_flavors::Slice::new(&mut wgr);
99 let used = wire_frames::encode_frame_err(ser, hdr, err).map_err(drop)?;
100 let len = used.len() as u16;
101 wgr.commit(len);
102
103 Ok(())
104 }
105}