0.2.0 |
|
---|---|
0.1.0 |
|
32 in #axum-server
22KB
436 代码行
axum_guard_combinator
https://crates.io/crates/axum_guard_combinator
这个库允许你在 Axum 服务器中的 Tower 服务层内部编写逻辑(或、与)组合器,该组合器提取实现的 Guard 类型的给定类型 T,并检查类型 T 的值与层组合器内部的输入值。以下是一个始终返回 true 的结构。
#[derive(Clone,Copy,Debug,PartialEq)]
pub struct Always;
impl Guard for Always {
fn check_guard(&self,_:&Self) -> bool {
true
}
}
#[async_trait::async_trait]
impl<B:Send+Sync> FromRequest<B> for Always {
type Rejection = ();
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
Ok(Self)
}
}
以下是一个将此结构与始终返回 false 的结构结合的测试用例
#[tokio::test]
async fn test_or_happy_path() {
let app = Router::new()
.route("/",get(ok
.layer(GuardLayer::with(Always.or(Never)))));
let response = app
.oneshot(
Request::builder()
.uri("/")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
}
您可以将组合器嵌套到任意深度
#[tokio::test]
async fn test_happy_nested() {
let app = Router::new()
.route("/",get(ok
.layer(GuardLayer::with(
Never.or(
Always.and(
Always.or(
Never)))))));
let response = app
.oneshot(
Request::builder()
.uri("/")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
}
您可以在层中输入数据,这些数据将在 Guard 实现的 check_guard 方法中评估
#[derive(Clone,Debug,PartialEq)]
pub struct ArbitraryData{
data:String,
}
impl Guard for ArbitraryData{
fn check_guard(&self, expected: &Self) -> bool {
*self == *expected
}
}
#[async_trait::async_trait]
impl<B:Send+Sync> FromRequest<B> for ArbitraryData {
type Rejection = ();
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
Ok(Self{
data: req.headers().get("data").unwrap()
.to_str().unwrap().to_string()
})
}
}
#[tokio::test]
async fn test_or_happy_path_with_data() {
let app = Router::new()
.route("/",get(ok
.layer(GuardLayer::with(ArbitraryData{
data:String::from("Hello World.")
}))));
let response = app
.oneshot(
Request::builder()
.uri("/")
.header("data","Hello World.")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
}
依赖关系
~6.5–9MB
~164K SLoC