ergot_base/interface_manager/utils/
cobs_stream.rs1use bbq2::{prod_cons::stream::StreamProducer, traits::bbqhdl::BbqHandle};
7use postcard::ser_flavors::{self, Flavor};
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: StreamProducer<Q>,
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.stream_producer(),
33 }
34 }
35
36 pub const fn new(prod: StreamProducer<Q>, mtu: u16) -> Self {
37 Self { mtu, prod }
38 }
39}
40
41#[allow(clippy::result_unit_err)] impl<Q> InterfaceSink for Sink<Q>
43where
44 Q: BbqHandle,
45{
46 fn send_ty<T: Serialize>(
47 &mut self,
48 hdr: &CommonHeader,
49 apdx: Option<&AnyAllAppendix>,
50 body: &T,
51 ) -> Result<(), ()> {
52 let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR;
53
54 if is_err {
55 return Err(());
57 }
58
59 let max_len = cobs::max_encoding_length(self.mtu as usize);
60 let mut wgr = self.prod.grant_exact(max_len).map_err(drop)?;
61
62 let ser = ser_flavors::Cobs::try_new(ser_flavors::Slice::new(&mut wgr)).map_err(drop)?;
63 let used = wire_frames::encode_frame_ty(ser, hdr, apdx, body).map_err(drop)?;
64 let len = used.len();
65 wgr.commit(len);
66
67 Ok(())
68 }
69
70 fn send_raw(&mut self, hdr: &CommonHeader, hdr_raw: &[u8], body: &[u8]) -> Result<(), ()> {
71 let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR;
72
73 if is_err {
74 return Err(());
76 }
77
78 let max_len = cobs::max_encoding_length(hdr_raw.len() + body.len());
79 let mut wgr = self.prod.grant_exact(max_len).map_err(drop)?;
80
81 let mut ser =
82 ser_flavors::Cobs::try_new(ser_flavors::Slice::new(&mut wgr)).map_err(drop)?;
83 ser.try_extend(hdr_raw).map_err(drop)?;
84 ser.try_extend(body).map_err(drop)?;
85 let fin = ser.finalize().map_err(drop)?;
86 let len = fin.len();
87 wgr.commit(len);
88
89 Ok(())
90 }
91
92 fn send_err(&mut self, hdr: &CommonHeader, err: ProtocolError) -> Result<(), ()> {
93 let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR;
94
95 if !is_err {
97 return Err(());
99 }
100
101 let max_len = cobs::max_encoding_length(self.mtu as usize);
102 let mut wgr = self.prod.grant_exact(max_len).map_err(drop)?;
103
104 let ser = ser_flavors::Cobs::try_new(ser_flavors::Slice::new(&mut wgr)).map_err(drop)?;
105 let used = wire_frames::encode_frame_err(ser, hdr, err).map_err(drop)?;
106 let len = used.len();
107 wgr.commit(len);
108
109 Ok(())
110 }
111}