mirror of
https://github.com/leptos-rs/leptos.git
synced 2025-12-27 09:54:41 -05:00
initial work on Actix middleware support
This commit is contained in:
@@ -118,9 +118,9 @@ pub fn Counters() -> impl IntoView {
|
||||
// This is the typical pattern for a CRUD app
|
||||
#[component]
|
||||
pub fn Counter() -> impl IntoView {
|
||||
let dec = create_action(|_: &()| adjust_server_count(-1, "decing".into()));
|
||||
let inc = create_action(|_: &()| adjust_server_count(1, "incing".into()));
|
||||
let clear = create_action(|_: &()| clear_server_count());
|
||||
let dec = create_action(|_| adjust_server_count(-1, "decing".into()));
|
||||
let inc = create_action(|_| adjust_server_count(1, "incing".into()));
|
||||
let clear = create_action(|_| clear_server_count());
|
||||
let counter = create_resource(
|
||||
move || {
|
||||
(
|
||||
@@ -222,10 +222,9 @@ pub fn FormCounter() -> impl IntoView {
|
||||
#[component]
|
||||
pub fn MultiuserCounter() -> impl IntoView {
|
||||
let dec =
|
||||
create_action(|_: &()| adjust_server_count(-1, "dec dec goose".into()));
|
||||
let inc =
|
||||
create_action(|_: &()| adjust_server_count(1, "inc inc moose".into()));
|
||||
let clear = create_action(|_: &()| clear_server_count());
|
||||
create_action(|_| adjust_server_count(-1, "dec dec goose".into()));
|
||||
let inc = create_action(|_| adjust_server_count(1, "inc inc moose".into()));
|
||||
let clear = create_action(|_| clear_server_count());
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
let multiplayer_value = {
|
||||
|
||||
@@ -21,7 +21,7 @@ async fn main() {
|
||||
|
||||
// run our app with hyper
|
||||
// `axum::Server` is a re-export of `hyper::Server`
|
||||
logging::log!("listening on {}", addr);
|
||||
leptos::logging::log!("listening on {}", addr);
|
||||
let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
|
||||
axum::serve(listener, app.into_make_service())
|
||||
.await
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#[cfg(feature = "ssr")]
|
||||
pub mod middleware;
|
||||
pub mod todo;
|
||||
|
||||
#[cfg(feature = "hydrate")]
|
||||
|
||||
58
examples/todo_app_sqlite/src/middleware.rs
Normal file
58
examples/todo_app_sqlite/src/middleware.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use actix_web::{
|
||||
dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
|
||||
Error,
|
||||
};
|
||||
use std::{
|
||||
future::{ready, Future, Ready},
|
||||
pin::Pin,
|
||||
};
|
||||
|
||||
pub struct LoggingLayer;
|
||||
|
||||
impl<S, B> Transform<S, ServiceRequest> for LoggingLayer
|
||||
where
|
||||
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
|
||||
S::Future: 'static,
|
||||
B: 'static,
|
||||
{
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Transform = LoggingService<S>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ready(Ok(LoggingService { service }))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LoggingService<S> {
|
||||
service: S,
|
||||
}
|
||||
|
||||
impl<S, B> Service<ServiceRequest> for LoggingService<S>
|
||||
where
|
||||
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
|
||||
S::Future: 'static,
|
||||
B: 'static,
|
||||
{
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type Future =
|
||||
Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
|
||||
|
||||
forward_ready!(service);
|
||||
|
||||
fn call(&self, req: ServiceRequest) -> Self::Future {
|
||||
println!("1. Middleware running before server fn.");
|
||||
|
||||
let fut = self.service.call(req);
|
||||
|
||||
Box::pin(async move {
|
||||
let res = fut.await?;
|
||||
println!("3. Middleware running after server fn.");
|
||||
Ok(res)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ pub async fn get_todos() -> Result<Vec<Todo>, ServerFnError> {
|
||||
}
|
||||
|
||||
#[server]
|
||||
#[middleware(crate::middleware::LoggingLayer)]
|
||||
pub async fn add_todo(title: String) -> Result<(), ServerFnError> {
|
||||
use self::ssr::*;
|
||||
|
||||
|
||||
@@ -93,8 +93,8 @@ where
|
||||
any(debug_assertions, feature = "ssr"),
|
||||
tracing::instrument(level = "trace", skip_all,)
|
||||
)]
|
||||
pub fn dispatch(&self, input: impl Into<I>) {
|
||||
self.0.with_value(|a| a.dispatch(input.into()))
|
||||
pub fn dispatch(&self, input: I) {
|
||||
self.0.with_value(|a| a.dispatch(input))
|
||||
}
|
||||
|
||||
/// Create an [Action].
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::{future::Future, pin::Pin};
|
||||
|
||||
/// An abstraction over a middleware layer, which can be used to add additional
|
||||
/// middleware layer to a [`Service`].
|
||||
pub trait Layer<Req, Res>: Send + Sync + 'static {
|
||||
pub trait Layer<Req, Res>: 'static {
|
||||
/// Adds this layer to the inner service.
|
||||
fn layer(&self, inner: BoxedService<Req, Res>) -> BoxedService<Req, Res>;
|
||||
}
|
||||
@@ -104,18 +104,53 @@ mod axum {
|
||||
|
||||
#[cfg(feature = "actix")]
|
||||
mod actix {
|
||||
use super::BoxedService;
|
||||
use crate::{
|
||||
request::actix::ActixRequest,
|
||||
response::{actix::ActixResponse, Res},
|
||||
ServerFnError,
|
||||
};
|
||||
use actix_web::{HttpRequest, HttpResponse};
|
||||
use actix_web::{
|
||||
dev::{Service, Transform},
|
||||
HttpRequest, HttpResponse,
|
||||
};
|
||||
use std::{
|
||||
fmt::{Debug, Display},
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
impl<T> super::Layer<HttpRequest, HttpResponse> for T
|
||||
where
|
||||
T: Transform<BoxedService<HttpRequest, HttpResponse>, HttpRequest>
|
||||
+ 'static, /* + Send
|
||||
+ Sync
|
||||
+ 'static,*/
|
||||
{
|
||||
fn layer(
|
||||
&self,
|
||||
inner: BoxedService<HttpRequest, HttpResponse>,
|
||||
) -> BoxedService<HttpRequest, HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> super::Layer<ActixRequest, ActixResponse> for T
|
||||
where
|
||||
T: Transform<BoxedService<ActixRequest, ActixResponse>, HttpRequest>
|
||||
//+ Send
|
||||
//+ Sync
|
||||
+ 'static,
|
||||
{
|
||||
fn layer(
|
||||
&self,
|
||||
inner: BoxedService<ActixRequest, ActixResponse>,
|
||||
) -> BoxedService<ActixRequest, ActixResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> super::Service<HttpRequest, HttpResponse> for S
|
||||
where
|
||||
S: actix_web::dev::Service<HttpRequest, Response = HttpResponse>,
|
||||
@@ -157,4 +192,46 @@ mod actix {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<Req> Service<Req> for BoxedService<HttpRequest, HttpResponse> {
|
||||
type Response = HttpResponse;
|
||||
type Error = ServerFnError;
|
||||
type Future = Pin<
|
||||
Box<
|
||||
dyn Future<Output = Result<Self::Response, Self::Error>> + Send,
|
||||
>,
|
||||
>;
|
||||
|
||||
fn poll_ready(
|
||||
&self,
|
||||
ctx: &mut Context<'_>,
|
||||
) -> Poll<Result<(), Self::Error>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn call(&self, req: Req) -> Self::Future {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Req> Service<Req> for BoxedService<ActixRequest, ActixResponse> {
|
||||
type Response = HttpResponse;
|
||||
type Error = ServerFnError;
|
||||
type Future = Pin<
|
||||
Box<
|
||||
dyn Future<Output = Result<Self::Response, Self::Error>> + Send,
|
||||
>,
|
||||
>;
|
||||
|
||||
fn poll_ready(
|
||||
&self,
|
||||
ctx: &mut Context<'_>,
|
||||
) -> Poll<Result<(), Self::Error>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn call(&self, req: Req) -> Self::Future {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user