1use bytes::Bytes;
2use futures::{Stream, StreamExt};
3use leptos::server_fn::{error::ServerFnError, request::Req};
4use spin_sdk::http::IncomingRequest;
5use std::borrow::Cow;
6
7#[derive(Debug)]
10pub struct SpinRequest {
11 pub req: IncomingRequest,
12 pub path_with_query: Option<String>,
13}
14impl SpinRequest {
15 pub fn new_from_req(req: IncomingRequest) -> Self {
16 SpinRequest {
17 path_with_query: req.path_with_query(),
18 req,
19 }
20 }
21}
22
23impl<CustErr> Req<CustErr> for SpinRequest
24where
25 CustErr: 'static,
26{
27 fn as_query(&self) -> Option<&str> {
28 self.path_with_query
29 .as_ref()
30 .and_then(|n| n.split_once('?').map(|(_, query)| query))
31 }
32
33 fn to_content_type(&self) -> Option<Cow<'_, str>> {
34 self.req
35 .headers()
36 .get(&"Content-Type".to_string())
37 .first()
38 .map(|h| String::from_utf8_lossy(h))
39 .map(Cow::into_owned)
40 .map(Cow::<'static, str>::Owned)
41 }
42
43 fn accepts(&self) -> Option<Cow<'_, str>> {
44 self.req
45 .headers()
46 .get(&"Accept".to_string())
47 .first()
48 .map(|h| String::from_utf8_lossy(h))
49 .map(Cow::into_owned)
50 .map(Cow::<'static, str>::Owned)
51 }
52
53 fn referer(&self) -> Option<Cow<'_, str>> {
54 self.req
55 .headers()
56 .get(&"Referer".to_string())
57 .first()
58 .map(|h| String::from_utf8_lossy(h))
59 .map(Cow::into_owned)
60 .map(Cow::<'static, str>::Owned)
61 }
62
63 async fn try_into_bytes(self) -> Result<Bytes, ServerFnError<CustErr>> {
64 let buf = self
65 .req
66 .into_body()
67 .await
68 .map_err(|e| ServerFnError::Deserialization(e.to_string()))?;
69 Ok(Bytes::copy_from_slice(&buf))
70 }
71
72 async fn try_into_string(self) -> Result<String, ServerFnError<CustErr>> {
73 let bytes = self.try_into_bytes().await?;
74 String::from_utf8(bytes.to_vec()).map_err(|e| ServerFnError::Deserialization(e.to_string()))
75 }
76
77 fn try_into_stream(
78 self,
79 ) -> Result<
80 impl Stream<Item = Result<Bytes, ServerFnError>> + Send + 'static,
81 ServerFnError<CustErr>,
82 > {
83 Ok(self.req.into_body_stream().map(|chunk| {
84 chunk
85 .map(|c| Bytes::copy_from_slice(&c))
86 .map_err(|e| ServerFnError::Deserialization(e.to_string()))
87 }))
88 }
89}