Make clippy happy, pass tests
This commit is contained in:
8 files changed
+57
-70
No files matched your search
@@ -45,7 +45,7 @@ impl UserData for PluginCommander {
|
|||||||
if cmd.is_empty() {
|
if cmd.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let cmd_name = cmd.get(0).unwrap();
|
let cmd_name = cmd.first().unwrap();
|
||||||
let mut command = Command::new(cmd_name);
|
let mut command = Command::new(cmd_name);
|
||||||
let t = cmd
|
let t = cmd
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ impl ProxyClient {
|
|||||||
pub fn add_proxy(mut router: Router, proxy: &WebProxyConfig) -> Result<Router> {
|
pub fn add_proxy(mut router: Router, proxy: &WebProxyConfig) -> Result<Router> {
|
||||||
let url: Uri = proxy.backend.parse()?;
|
let url: Uri = proxy.backend.parse()?;
|
||||||
let path = url.path().to_string();
|
let path = url.path().to_string();
|
||||||
let trimmed_path = path.trim_end_matches('/');
|
let trimmed_path = path.trim_start_matches('/');
|
||||||
|
|
||||||
if trimmed_path.is_empty() {
|
if trimmed_path.is_empty() {
|
||||||
return Err(crate::Error::ProxySetupError(format!(
|
return Err(crate::Error::ProxySetupError(format!(
|
||||||
@@ -65,14 +65,11 @@ pub fn add_proxy(mut router: Router, proxy: &WebProxyConfig) -> Result<Router> {
|
|||||||
|
|
||||||
let client = ProxyClient::new(url);
|
let client = ProxyClient::new(url);
|
||||||
|
|
||||||
// We also match everything after the path using a wildcard matcher.
|
|
||||||
let wildcard_client = client.clone();
|
|
||||||
|
|
||||||
router = router.route(
|
router = router.route(
|
||||||
// Always remove trailing /'s so that the exact route
|
// Always remove trailing /'s so that the exact route
|
||||||
// matches.
|
// matches.
|
||||||
trimmed_path,
|
&format!("/*{}", trimmed_path.trim_end_matches('/')),
|
||||||
any(move |req| async move {
|
any(move |req: Request<MyBody>| async move {
|
||||||
client
|
client
|
||||||
.send(req)
|
.send(req)
|
||||||
.await
|
.await
|
||||||
@@ -80,19 +77,6 @@ pub fn add_proxy(mut router: Router, proxy: &WebProxyConfig) -> Result<Router> {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Wildcard match anything else _after_ the backend URL's path.
|
|
||||||
// Note that we know `path` ends with a trailing `/` in this branch,
|
|
||||||
// so `wildcard` will look like `http://localhost/api/*proxywildcard`.
|
|
||||||
let wildcard = format!("{}/*proxywildcard", trimmed_path);
|
|
||||||
router = router.route(
|
|
||||||
&wildcard,
|
|
||||||
any(move |req| async move {
|
|
||||||
wildcard_client
|
|
||||||
.send(req)
|
|
||||||
.await
|
|
||||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
Ok(router)
|
Ok(router)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,14 +85,17 @@ mod test {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use axum::{extract::Path, Router};
|
use axum::Router;
|
||||||
use axum_server::{Handle, Server};
|
use axum_server::{Handle, Server};
|
||||||
|
|
||||||
async fn setup_servers(mut config: WebProxyConfig) -> String {
|
async fn setup_servers(mut config: WebProxyConfig) -> String {
|
||||||
let backend_router = Router::new().route(
|
let backend_router =
|
||||||
"/*path",
|
Router::new().route(
|
||||||
any(|path: Path<String>| async move { format!("backend: {}", path.0) }),
|
"/*path",
|
||||||
);
|
any(|request: axum::extract::Request| async move {
|
||||||
|
format!("backend: {}", request.uri())
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// The API backend server
|
// The API backend server
|
||||||
let backend_handle_handle = Handle::new();
|
let backend_handle_handle = Handle::new();
|
||||||
@@ -123,7 +110,7 @@ mod test {
|
|||||||
|
|
||||||
// Set the user's config to this dummy API we just built so we can test it
|
// Set the user's config to this dummy API we just built so we can test it
|
||||||
let backend_addr = backend_handle_handle.listening().await.unwrap();
|
let backend_addr = backend_handle_handle.listening().await.unwrap();
|
||||||
config.backend = dbg!(format!("http://{}{}", backend_addr, config.backend));
|
config.backend = format!("http://{}{}", backend_addr, config.backend);
|
||||||
|
|
||||||
// Now set up our actual filesystem server
|
// Now set up our actual filesystem server
|
||||||
let router = super::add_proxy(Router::new(), &config);
|
let router = super::add_proxy(Router::new(), &config);
|
||||||
@@ -160,11 +147,11 @@ mod test {
|
|||||||
.text()
|
.text()
|
||||||
.await
|
.await
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
"backend: api"
|
"backend: /api"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
reqwest::get(dbg!(format!("http://{}/api/", server_addr)))
|
reqwest::get(format!("http://{}/api/", server_addr))
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.text()
|
.text()
|
||||||
@@ -174,7 +161,7 @@ mod test {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
reqwest::get(format!("http://{}/api/subpath", server_addr))
|
reqwest::get(format!("http://{server_addr}/api/subpath"))
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.text()
|
.text()
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ async fn main() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let _ = register_explicit::<PostServerData>();
|
register_explicit::<PostServerData>();
|
||||||
let _ = register_explicit::<GetServerData>();
|
register_explicit::<GetServerData>();
|
||||||
|
|
||||||
axum::serve(
|
axum::serve(
|
||||||
listener,
|
listener,
|
||||||
|
|||||||
@@ -302,6 +302,13 @@ fn apply_request_parts_to_response<B>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AxumHandler<F> = (
|
||||||
|
F,
|
||||||
|
ServeConfig,
|
||||||
|
SSRState,
|
||||||
|
Arc<dyn Fn() -> VirtualDom + Send + Sync>,
|
||||||
|
);
|
||||||
|
|
||||||
/// SSR renderer handler for Axum with added context injection.
|
/// SSR renderer handler for Axum with added context injection.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@@ -350,18 +357,13 @@ fn apply_request_parts_to_response<B>(
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn render_handler_with_context<F: FnMut(&mut DioxusServerContext)>(
|
pub async fn render_handler_with_context<F: FnMut(&mut DioxusServerContext)>(
|
||||||
State((mut inject_context, cfg, ssr_state, virtual_dom_factory)): State<(
|
State((mut inject_context, cfg, ssr_state, virtual_dom_factory)): State<AxumHandler<F>>,
|
||||||
F,
|
|
||||||
ServeConfig,
|
|
||||||
SSRState,
|
|
||||||
Arc<dyn Fn() -> VirtualDom + Send + Sync>,
|
|
||||||
)>,
|
|
||||||
request: Request<Body>,
|
request: Request<Body>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let (parts, _) = request.into_parts();
|
let (parts, _) = request.into_parts();
|
||||||
let url = parts.uri.path_and_query().unwrap().to_string();
|
let url = parts.uri.path_and_query().unwrap().to_string();
|
||||||
let parts: Arc<tokio::sync::RwLock<http::request::Parts>> =
|
let parts: Arc<tokio::sync::RwLock<http::request::Parts>> =
|
||||||
Arc::new(tokio::sync::RwLock::new(parts.into()));
|
Arc::new(tokio::sync::RwLock::new(parts));
|
||||||
let mut server_context = DioxusServerContext::new(parts.clone());
|
let mut server_context = DioxusServerContext::new(parts.clone());
|
||||||
inject_context(&mut server_context);
|
inject_context(&mut server_context);
|
||||||
|
|
||||||
@@ -384,13 +386,15 @@ pub async fn render_handler_with_context<F: FnMut(&mut DioxusServerContext)>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RenderHandlerExtractor = (
|
||||||
|
ServeConfig,
|
||||||
|
Arc<dyn Fn() -> VirtualDom + Send + Sync>,
|
||||||
|
SSRState,
|
||||||
|
);
|
||||||
|
|
||||||
/// SSR renderer handler for Axum
|
/// SSR renderer handler for Axum
|
||||||
pub async fn render_handler(
|
pub async fn render_handler(
|
||||||
State((cfg, virtual_dom_factory, ssr_state)): State<(
|
State((cfg, virtual_dom_factory, ssr_state)): State<RenderHandlerExtractor>,
|
||||||
ServeConfig,
|
|
||||||
Arc<dyn Fn() -> VirtualDom + Send + Sync>,
|
|
||||||
SSRState,
|
|
||||||
)>,
|
|
||||||
request: Request<Body>,
|
request: Request<Body>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
render_handler_with_context(
|
render_handler_with_context(
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ impl SsrRendererPool {
|
|||||||
SERVER_CONTEXT.with(|ctx| ctx.replace(server_context));
|
SERVER_CONTEXT.with(|ctx| ctx.replace(server_context));
|
||||||
// poll the future, which may call server_context()
|
// poll the future, which may call server_context()
|
||||||
tracing::info!("Rebuilding vdom");
|
tracing::info!("Rebuilding vdom");
|
||||||
let _ = vdom.rebuild(&mut NoOpMutations);
|
vdom.rebuild(&mut NoOpMutations);
|
||||||
vdom.wait_for_suspense().await;
|
vdom.wait_for_suspense().await;
|
||||||
tracing::info!("Suspense resolved");
|
tracing::info!("Suspense resolved");
|
||||||
// after polling the future, we need to restore the context
|
// after polling the future, we need to restore the context
|
||||||
@@ -76,9 +76,11 @@ impl SsrRendererPool {
|
|||||||
tx.send(Ok((renderer, RenderFreshness::now(None), html)));
|
tx.send(Ok((renderer, RenderFreshness::now(None), html)));
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
dioxus_ssr::incremental::IncrementalRendererError::Other(
|
_ = tx.send(Err(
|
||||||
Box::new(err),
|
dioxus_ssr::incremental::IncrementalRendererError::Other(
|
||||||
);
|
Box::new(err),
|
||||||
|
),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -113,7 +115,7 @@ impl SsrRendererPool {
|
|||||||
.with(|ctx| ctx.replace(Box::new(server_context)));
|
.with(|ctx| ctx.replace(Box::new(server_context)));
|
||||||
// poll the future, which may call server_context()
|
// poll the future, which may call server_context()
|
||||||
tracing::info!("Rebuilding vdom");
|
tracing::info!("Rebuilding vdom");
|
||||||
let _ = vdom.rebuild(&mut NoOpMutations);
|
vdom.rebuild(&mut NoOpMutations);
|
||||||
vdom.wait_for_suspense().await;
|
vdom.wait_for_suspense().await;
|
||||||
tracing::info!("Suspense resolved");
|
tracing::info!("Suspense resolved");
|
||||||
// after polling the future, we need to restore the context
|
// after polling the future, we need to restore the context
|
||||||
@@ -184,26 +186,21 @@ impl SSRState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Render the application to HTML.
|
/// Render the application to HTML.
|
||||||
pub fn render<'a>(
|
pub async fn render<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
route: String,
|
route: String,
|
||||||
cfg: &'a ServeConfig,
|
cfg: &'a ServeConfig,
|
||||||
virtual_dom_factory: impl FnOnce() -> VirtualDom + Send + Sync + 'static,
|
virtual_dom_factory: impl FnOnce() -> VirtualDom + Send + Sync + 'static,
|
||||||
server_context: &'a DioxusServerContext,
|
server_context: &'a DioxusServerContext,
|
||||||
) -> impl std::future::Future<
|
) -> Result<RenderResponse, dioxus_ssr::incremental::IncrementalRendererError> {
|
||||||
Output = Result<RenderResponse, dioxus_ssr::incremental::IncrementalRendererError>,
|
let ServeConfig { .. } = cfg;
|
||||||
> + Send
|
|
||||||
+ 'a {
|
|
||||||
async move {
|
|
||||||
let ServeConfig { .. } = cfg;
|
|
||||||
|
|
||||||
let (freshness, html) = self
|
let (freshness, html) = self
|
||||||
.renderers
|
.renderers
|
||||||
.render_to(cfg, route, virtual_dom_factory, server_context)
|
.render_to(cfg, route, virtual_dom_factory, server_context)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(RenderResponse { html, freshness })
|
Ok(RenderResponse { html, freshness })
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +318,7 @@ impl RenderResponse {
|
|||||||
fn pre_renderer() -> Renderer {
|
fn pre_renderer() -> Renderer {
|
||||||
let mut renderer = Renderer::default();
|
let mut renderer = Renderer::default();
|
||||||
renderer.pre_render = true;
|
renderer.pre_render = true;
|
||||||
renderer.into()
|
renderer
|
||||||
}
|
}
|
||||||
|
|
||||||
fn incremental_pre_renderer(
|
fn incremental_pre_renderer(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::io::Read;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/// A ServeConfig is used to configure how to serve a Dioxus application. It contains information about how to serve static assets, and what content to render with [`dioxus-ssr`].
|
/// A ServeConfig is used to configure how to serve a Dioxus application. It contains information about how to serve static assets, and what content to render with [`dioxus-ssr`].
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Default)]
|
||||||
pub struct ServeConfigBuilder {
|
pub struct ServeConfigBuilder {
|
||||||
pub(crate) root_id: Option<&'static str>,
|
pub(crate) root_id: Option<&'static str>,
|
||||||
pub(crate) index_path: Option<PathBuf>,
|
pub(crate) index_path: Option<PathBuf>,
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ mod server_fn_impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::thread_local! {
|
std::thread_local! {
|
||||||
pub(crate) static SERVER_CONTEXT: std::cell::RefCell<Box<DioxusServerContext>> = std::cell::RefCell::new(Box::new(DioxusServerContext::default() ));
|
pub(crate) static SERVER_CONTEXT: std::cell::RefCell<Box<DioxusServerContext>> = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get information about the current server request.
|
/// Get information about the current server request.
|
||||||
@@ -218,7 +218,7 @@ impl<T: Send + Sync + Clone + 'static> FromServerContext for FromContext<T> {
|
|||||||
type Rejection = NotFoundInServerContext<T>;
|
type Rejection = NotFoundInServerContext<T>;
|
||||||
|
|
||||||
async fn from_request(req: &DioxusServerContext) -> Result<Self, Self::Rejection> {
|
async fn from_request(req: &DioxusServerContext) -> Result<Self, Self::Rejection> {
|
||||||
Ok(Self(req.clone().get::<T>().ok_or_else(|| {
|
Ok(Self(req.clone().get::<T>().ok_or({
|
||||||
NotFoundInServerContext::<T>(std::marker::PhantomData::<T>)
|
NotFoundInServerContext::<T>(std::marker::PhantomData::<T>)
|
||||||
})?))
|
})?))
|
||||||
}
|
}
|
||||||
@@ -239,6 +239,6 @@ impl<
|
|||||||
type Rejection = R;
|
type Rejection = R;
|
||||||
|
|
||||||
async fn from_request(req: &DioxusServerContext) -> Result<Self, Self::Rejection> {
|
async fn from_request(req: &DioxusServerContext) -> Result<Self, Self::Rejection> {
|
||||||
Ok(I::from_request_parts(&mut *req.request_parts_mut(), &()).await?)
|
Ok(I::from_request_parts(&mut req.request_parts_mut(), &()).await?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,8 +166,8 @@ where
|
|||||||
///
|
///
|
||||||
/// Panics if the function is not called in a dioxus runtime with a Liveview context.
|
/// Panics if the function is not called in a dioxus runtime with a Liveview context.
|
||||||
pub fn new_with_initial_path(initial_path: R) -> Self {
|
pub fn new_with_initial_path(initial_path: R) -> Self {
|
||||||
let (action_tx, action_rx) = tokio::sync::mpsc::unbounded_channel::<Action<R>>();
|
let (action_tx, mut action_rx) = tokio::sync::mpsc::unbounded_channel::<Action<R>>();
|
||||||
let action_rx = Arc::new(Mutex::new(action_rx));
|
|
||||||
let timeline = Arc::new(Mutex::new(Timeline::new(initial_path)));
|
let timeline = Arc::new(Mutex::new(Timeline::new(initial_path)));
|
||||||
let updater_callback: Arc<RwLock<Arc<dyn Fn() + Send + Sync>>> =
|
let updater_callback: Arc<RwLock<Arc<dyn Fn() + Send + Sync>>> =
|
||||||
Arc::new(RwLock::new(Arc::new(|| {})));
|
Arc::new(RwLock::new(Arc::new(|| {})));
|
||||||
@@ -181,12 +181,11 @@ where
|
|||||||
// Listen to server actions
|
// Listen to server actions
|
||||||
spawn({
|
spawn({
|
||||||
let timeline = timeline.clone();
|
let timeline = timeline.clone();
|
||||||
let action_rx = action_rx.clone();
|
|
||||||
let create_eval = create_eval.clone();
|
let create_eval = create_eval.clone();
|
||||||
async move {
|
async move {
|
||||||
let mut action_rx = action_rx.lock().expect("unpoisoned mutex");
|
|
||||||
loop {
|
loop {
|
||||||
let eval = action_rx.recv().await.expect("sender to exist");
|
let eval = action_rx.recv().await.expect("sender to exist");
|
||||||
|
|
||||||
let _ = match eval {
|
let _ = match eval {
|
||||||
Action::GoBack => create_eval(
|
Action::GoBack => create_eval(
|
||||||
r#"
|
r#"
|
||||||
|
|||||||
Reference in new issue
Block a user