ergot_base/interface_manager/
cobs_stream.rs

1use bbq2::{prod_cons::stream::StreamProducer, traits::bbqhdl::BbqHandle};
2use postcard::ser_flavors;
3use serde::Serialize;
4
5use crate::{
6    FrameKind, Key, ProtocolError,
7    interface_manager::wire_frames::{self, CommonHeader},
8};
9
10pub struct Interface<Q>
11where
12    Q: BbqHandle,
13{
14    pub(crate) mtu: u16,
15    pub(crate) prod: StreamProducer<Q>,
16}
17
18#[allow(clippy::result_unit_err)] // todo
19impl<Q> Interface<Q>
20where
21    Q: BbqHandle,
22{
23    pub fn send_ty<T: Serialize>(
24        &mut self,
25        hdr: &CommonHeader,
26        key: Option<&Key>,
27        body: &T,
28    ) -> Result<(), ()> {
29        let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR.0;
30
31        if is_err {
32            // todo: use a different interface for this
33            return Err(());
34        }
35
36        let max_len = cobs::max_encoding_length(self.mtu as usize);
37        let mut wgr = self.prod.grant_exact(max_len)?;
38
39        let ser = ser_flavors::Cobs::try_new(ser_flavors::Slice::new(&mut wgr)).map_err(drop)?;
40        let used = wire_frames::encode_frame_ty(ser, hdr, key, body).map_err(drop)?;
41        let len = used.len();
42        wgr.commit(len);
43
44        Ok(())
45    }
46
47    pub fn send_raw(
48        &mut self,
49        hdr: &CommonHeader,
50        key: Option<&Key>,
51        body: &[u8],
52    ) -> Result<(), ()> {
53        let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR.0;
54
55        if is_err {
56            // todo: use a different interface for this
57            return Err(());
58        }
59
60        let max_len = cobs::max_encoding_length(self.mtu as usize);
61        let mut wgr = self.prod.grant_exact(max_len)?;
62
63        let ser = ser_flavors::Cobs::try_new(ser_flavors::Slice::new(&mut wgr)).map_err(drop)?;
64        let used = wire_frames::encode_frame_raw(ser, hdr, key, body).map_err(drop)?;
65        let len = used.len();
66        wgr.commit(len);
67
68        Ok(())
69    }
70
71    pub fn send_err(&mut self, hdr: &CommonHeader, err: ProtocolError) -> Result<(), ()> {
72        let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR.0;
73
74        // note: here it SHOULD be an err!
75        if !is_err {
76            // todo: use a different interface for this
77            return Err(());
78        }
79
80        let max_len = cobs::max_encoding_length(self.mtu as usize);
81        let mut wgr = self.prod.grant_exact(max_len)?;
82
83        let ser = ser_flavors::Cobs::try_new(ser_flavors::Slice::new(&mut wgr)).map_err(drop)?;
84        let used = wire_frames::encode_frame_err(ser, hdr, err).map_err(drop)?;
85        let len = used.len();
86        wgr.commit(len);
87
88        Ok(())
89    }
90}