trillium_http/
synthetic.rs1use crate::{
2    after_send::AfterSend, http_config::DEFAULT_CONFIG, received_body::ReceivedBodyState,
3    transport::Transport, Conn, Headers, KnownHeaderName, Method, StateSet, Stopper, Version,
4};
5use futures_lite::io::{AsyncRead, AsyncWrite, Cursor, Result};
6use std::{
7    pin::Pin,
8    task::{Context, Poll},
9    time::Instant,
10};
11
12#[derive(Debug)]
20pub struct Synthetic {
21    data: Cursor<Vec<u8>>,
22    closed: bool,
23}
24
25impl AsyncRead for Synthetic {
26    fn poll_read(
27        mut self: Pin<&mut Self>,
28        cx: &mut Context<'_>,
29        buf: &mut [u8],
30    ) -> Poll<Result<usize>> {
31        let Synthetic { data, closed } = &mut *self;
32        if *closed {
33            Poll::Ready(Ok(0))
34        } else {
35            match Pin::new(data).poll_read(cx, buf) {
36                Poll::Ready(Ok(0)) => Poll::Pending,
37                other => other,
38            }
39        }
40    }
41}
42
43impl Synthetic {
44    pub fn len(&self) -> Option<usize> {
46        match self.data.get_ref().len() {
48            0 => None,
49            n => Some(n),
50        }
51    }
52
53    pub fn is_empty(&self) -> bool {
55        self.data.get_ref().is_empty()
56    }
57
58    pub fn close(&mut self) {
60        self.closed = true;
61    }
62}
63
64impl Transport for Synthetic {}
65
66impl AsyncWrite for Synthetic {
67    fn poll_write(self: Pin<&mut Self>, _cx: &mut Context<'_>, _buf: &[u8]) -> Poll<Result<usize>> {
68        Poll::Ready(Ok(0))
69    }
70
71    fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>> {
72        Poll::Ready(Ok(()))
73    }
74
75    fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>> {
76        Poll::Ready(Ok(()))
77    }
78}
79
80impl From<Cursor<Vec<u8>>> for Synthetic {
81    fn from(data: Cursor<Vec<u8>>) -> Self {
82        Self {
83            data,
84            closed: false,
85        }
86    }
87}
88
89impl From<Vec<u8>> for Synthetic {
90    fn from(v: Vec<u8>) -> Self {
91        Cursor::new(v).into()
92    }
93}
94
95impl From<&[u8]> for Synthetic {
96    fn from(v: &[u8]) -> Self {
97        v.to_owned().into()
98    }
99}
100
101impl From<String> for Synthetic {
102    fn from(v: String) -> Self {
103        v.into_bytes().into()
104    }
105}
106
107impl From<&str> for Synthetic {
108    fn from(v: &str) -> Self {
109        v.as_bytes().into()
110    }
111}
112
113impl From<()> for Synthetic {
114    fn from((): ()) -> Self {
115        Vec::new().into()
116    }
117}
118
119impl From<Option<Vec<u8>>> for Synthetic {
120    fn from(v: Option<Vec<u8>>) -> Self {
121        v.unwrap_or_default().into()
122    }
123}
124
125impl Conn<Synthetic> {
126    pub fn new_synthetic(
136        method: Method,
137        path: impl Into<String>,
138        body: impl Into<Synthetic>,
139    ) -> Self {
140        let transport = body.into();
141        let mut request_headers = Headers::new();
142        request_headers.insert(
143            KnownHeaderName::ContentLength,
144            transport.len().unwrap_or_default().to_string(),
145        );
146
147        Self {
148            transport,
149            request_headers,
150            response_headers: Headers::new(),
151            path: path.into(),
152            method,
153            status: None,
154            version: Version::Http1_1,
155            state: StateSet::new(),
156            response_body: None,
157            buffer: Vec::with_capacity(DEFAULT_CONFIG.request_buffer_initial_len).into(),
158            request_body_state: ReceivedBodyState::Start,
159            secure: false,
160            stopper: Stopper::new(),
161            after_send: AfterSend::default(),
162            start_time: Instant::now(),
163            peer_ip: None,
164            http_config: DEFAULT_CONFIG,
165        }
166    }
167
168    pub fn close(&mut self) {
170        self.transport.close();
171    }
172
173    pub fn replace_body(&mut self, body: impl Into<Synthetic>) {
177        let transport = body.into();
178        self.request_headers_mut().insert(
179            KnownHeaderName::ContentLength,
180            transport.len().unwrap_or_default().to_string(),
181        );
182        self.transport = transport;
183        self.request_body_state = ReceivedBodyState::default();
184    }
185}