use std::sync::Arc;
use crate::{Endpoint, HttpEndpoint, HttpResponse, Server};
use tauri::{async_runtime::block_on, http::ResponseBuilder, AppHandle, Runtime};
use tokio::task::block_in_place;
impl<TEndpoint> Endpoint<TEndpoint>
where
TEndpoint: HttpEndpoint,
{
pub fn tauri_uri_scheme<R: Runtime>(
mut self,
uri_scheme: impl Into<String>,
) -> impl Fn(
&AppHandle<R>,
&tauri::http::Request,
) -> Result<tauri::http::Response, Box<dyn std::error::Error>>
+ Send
+ Sync
+ 'static {
let (_, methods) = self.endpoint.register();
let endpoint = Arc::new(self.endpoint);
let methods = methods.as_ref().to_vec();
let uri_scheme = uri_scheme.into();
let url1 = format!("{}://localhost/", uri_scheme);
let url2 = format!("{}://", uri_scheme);
let url3 = format!("http://{}.localhost/", uri_scheme);
move |handle, req| {
let resp = if !methods.contains(req.method()) {
#[allow(clippy::unwrap_used)] http::Response::builder().status(405).body(vec![]).unwrap()
} else {
let uri = req.uri();
let uri = uri
.replace(&url1, &url3) .replace(&url2, &url3);
let uri = percent_encoding::percent_decode(uri.as_bytes())
.decode_utf8_lossy()
.to_string();
let mut r = http::Request::builder()
.method(req.method())
.uri(uri)
.extension(handle.clone());
for (key, value) in req.headers() {
r = r.header(key, value);
}
#[allow(clippy::unwrap_used)] let req = r.body(req.body().clone()).unwrap();
match block_in_place(|| {
block_on(endpoint.handler(crate::Request::new(req, Server::Tauri)))
})
.into_response()
{
Ok(resp) => resp,
Err(_err) => {
#[allow(clippy::unwrap_used)] http::Response::builder().status(500).body(vec![]).unwrap()
}
}
};
let mut r = ResponseBuilder::new()
.version(resp.version())
.status(resp.status());
for (key, value) in resp.headers() {
r = r.header(key, value);
}
r.body(resp.into_body())
}
}
}
impl crate::Request {
pub fn get_tauri_app_handle<R>(&self) -> Option<&AppHandle<R>>
where
R: Runtime,
{
self.0.extensions.get::<AppHandle<R>>()
}
}