mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
This commit is contained in:
parent
c7607f6fcc
commit
0d4862b238
3 changed files with 98 additions and 4 deletions
|
@ -27,7 +27,12 @@ use leptos_meta::*;
|
|||
use leptos_router::*;
|
||||
use parking_lot::RwLock;
|
||||
use regex::Regex;
|
||||
use std::{fmt::Display, future::Future, pin::Pin, sync::Arc};
|
||||
use std::{
|
||||
fmt::{Debug, Display},
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
sync::Arc,
|
||||
};
|
||||
#[cfg(debug_assertions)]
|
||||
use tracing::instrument;
|
||||
/// This struct lets you define headers and override the status of the Response from an Element or a Server Function
|
||||
|
@ -1410,6 +1415,58 @@ where
|
|||
Ok(f.call(input).await)
|
||||
}
|
||||
|
||||
/// A helper to make it easier to use Axum extractors in server functions, with a
|
||||
/// simpler API than [`extract`].
|
||||
///
|
||||
/// It is generic over some type `T` that implements [`FromRequestParts`] and can
|
||||
/// therefore be used in an extractor. The compiler can often infer this type.
|
||||
///
|
||||
/// Any error that occurs during extraction is converted to a [`ServerFnError`].
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// // MyQuery is some type that implements `Deserialize + Serialize`
|
||||
/// #[server]
|
||||
/// pub async fn query_extract() -> Result<MyQuery, ServerFnError> {
|
||||
/// use actix_web::web::Query;
|
||||
/// use leptos_actix::*;
|
||||
/// let Query(data) = extractor().await?;
|
||||
/// Ok(data)
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn extractor<T>() -> Result<T, ServerFnError>
|
||||
where
|
||||
T: actix_web::FromRequest,
|
||||
<T as FromRequest>::Error: Debug,
|
||||
{
|
||||
let req = use_context::<actix_web::HttpRequest>()
|
||||
.expect("HttpRequest should have been provided via context");
|
||||
|
||||
if let Some(body) = use_context::<Bytes>() {
|
||||
let (_, mut payload) = actix_http::h1::Payload::create(false);
|
||||
payload.unread_data(body);
|
||||
T::from_request(&req, &mut dev::Payload::from(payload))
|
||||
} else {
|
||||
T::extract(&req)
|
||||
}
|
||||
.await
|
||||
.map_err(|e| ServerFnError::ServerError(format!("{e:?}")))
|
||||
}
|
||||
|
||||
/// A macro that makes it easier to use extractors in server functions. The macro
|
||||
/// takes a type or types, and extracts them from the request, returning from the
|
||||
/// server function with an `Err(_)` if there is an error during extraction.
|
||||
/// ```rust,ignore
|
||||
/// let info = extract!(ConnectionInfo);
|
||||
/// let Query(data) = extract!(Query<Search>);
|
||||
/// let (info, Query(data)) = extract!(ConnectionInfo, Query<Search>);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! extract {
|
||||
($($x:ty),+) => {
|
||||
$crate::extract(|fields: ($($x),+)| async move { fields }).await?
|
||||
};
|
||||
}
|
||||
|
||||
// Drawn from the Actix Handler implementation
|
||||
// https://github.com/actix/actix-web/blob/19c9d858f25e8262e14546f430d713addb397e96/actix-web/src/handler.rs#L124
|
||||
pub trait Extractor<T> {
|
||||
|
@ -1417,6 +1474,7 @@ pub trait Extractor<T> {
|
|||
|
||||
fn call(self, args: T) -> Self::Future;
|
||||
}
|
||||
|
||||
macro_rules! factory_tuple ({ $($param:ident)* } => {
|
||||
impl<Func, Fut, $($param,)*> Extractor<($($param,)*)> for Func
|
||||
where
|
||||
|
|
|
@ -8,7 +8,9 @@ repository = "https://github.com/leptos-rs/leptos"
|
|||
description = "Axum integrations for the Leptos web framework."
|
||||
|
||||
[dependencies]
|
||||
axum = { version = "0.6", default-features = false, features=["matched-path"] }
|
||||
axum = { version = "0.6", default-features = false, features = [
|
||||
"matched-path",
|
||||
] }
|
||||
futures = "0.3"
|
||||
http = "0.2.8"
|
||||
hyper = "0.14.23"
|
||||
|
@ -28,4 +30,4 @@ cfg-if = "1.0.0"
|
|||
nonce = ["leptos/nonce"]
|
||||
wasm = []
|
||||
default = ["tokio/full", "axum/macros"]
|
||||
experimental-islands = ["leptos_integration_utils/experimental-islands"]
|
||||
experimental-islands = ["leptos_integration_utils/experimental-islands"]
|
||||
|
|
|
@ -35,7 +35,7 @@ use leptos_meta::{generate_head_metadata_separated, MetaContext};
|
|||
use leptos_router::*;
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::RwLock;
|
||||
use std::{io, pin::Pin, sync::Arc, thread::available_parallelism};
|
||||
use std::{fmt::Debug, io, pin::Pin, sync::Arc, thread::available_parallelism};
|
||||
use tokio_util::task::LocalPoolHandle;
|
||||
use tracing::Instrument;
|
||||
/// A struct to hold the parts of the incoming Request. Since `http::Request` isn't cloneable, we're forced
|
||||
|
@ -1826,6 +1826,40 @@ where
|
|||
extract_with_state((), f).await
|
||||
}
|
||||
|
||||
/// A helper to make it easier to use Axum extractors in server functions, with a
|
||||
/// simpler API than [`extract`].
|
||||
///
|
||||
/// It is generic over some type `T` that implements [`FromRequestParts`] and can
|
||||
/// therefore be used in an extractor. The compiler can often infer this type.
|
||||
///
|
||||
/// Any error that occurs during extraction is converted to a [`ServerFnError`].
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// // MyQuery is some type that implements `Deserialize + Serialize`
|
||||
/// #[server]
|
||||
/// pub async fn query_extract() -> Result<MyQuery, ServerFnError> {
|
||||
/// use axum::{extract::Query, http::Method};
|
||||
/// use leptos_axum::*;
|
||||
/// let Query(query) = extractor().await?;
|
||||
///
|
||||
/// Ok(query)
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn extractor<T>() -> Result<T, ServerFnError>
|
||||
where
|
||||
T: Sized + FromRequestParts<()>,
|
||||
T::Rejection: Debug,
|
||||
{
|
||||
let ctx = use_context::<ExtractorHelper>().expect(
|
||||
"should have had ExtractorHelper provided by the leptos_axum \
|
||||
integration",
|
||||
);
|
||||
let mut parts = ctx.parts.lock().await;
|
||||
T::from_request_parts(&mut parts, &())
|
||||
.await
|
||||
.map_err(|e| ServerFnError::ServerError(format!("{e:?}")))
|
||||
}
|
||||
|
||||
/// A helper to make it easier to use Axum extractors in server functions. This takes
|
||||
/// a handler function and state as its arguments. The handler rules similar to Axum
|
||||
/// [handlers](https://docs.rs/axum/latest/axum/extract/index.html#intro): it is an async function
|
||||
|
|
Loading…
Reference in a new issue