drogue_http_client/
tcp.rs

1//! TCP stack implementation of [`Sink`] and [`Source`].
2
3use crate::{Request, ResponseHandler, Sink, Source};
4use core::str::from_utf8;
5use drogue_network::tcp::TcpStack;
6use heapless::ArrayLength;
7
8pub struct TcpSocketSinkSource<'tcp, T>
9where
10    T: TcpStack,
11{
12    stack: &'tcp mut T,
13    socket: &'tcp mut T::TcpSocket,
14}
15
16impl<'tcp, T> TcpSocketSinkSource<'tcp, T>
17where
18    T: TcpStack,
19{
20    pub fn from(stack: &'tcp mut T, socket: &'tcp mut T::TcpSocket) -> Self {
21        TcpSocketSinkSource { stack, socket }
22    }
23}
24
25impl<'tcp, T> Source for TcpSocketSinkSource<'tcp, T>
26where
27    T: TcpStack,
28{
29    type Error = T::Error;
30
31    fn pipe_data<IN, R>(&mut self, request: &mut Request<IN, R>) -> Result<(), Self::Error>
32    where
33        IN: ArrayLength<u8>,
34        R: ResponseHandler,
35    {
36        let mut buffer = [0u8; 512];
37        while !request.is_complete() {
38            match self.stack.read(self.socket, &mut buffer) {
39                Ok(len) => {
40                    request.push_data(&buffer[0..len]);
41                }
42                Err(nb::Error::WouldBlock) => {}
43                Err(nb::Error::Other(e)) => return Err(e),
44            }
45        }
46        Ok(())
47    }
48}
49
50impl<'tcp, T> Sink for TcpSocketSinkSource<'tcp, T>
51where
52    T: TcpStack,
53{
54    fn send(&mut self, data: &[u8]) -> Result<usize, ()> {
55        log::info!("Sending: {:?}", from_utf8(data));
56        self.stack.write(self.socket, data).map_err(|_| ())
57    }
58}