mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-23 15:51:06 +01:00
allow to specify multi pattern for resources
This commit is contained in:
parent
7882f545e5
commit
f86ce0390e
@ -8,6 +8,7 @@
|
||||
|
||||
* Allow to gracefully stop test server via `TestServer::stop()`
|
||||
|
||||
* Allow to specify multi-patterns for resources
|
||||
|
||||
## [2.0.0-rc] - 2019-12-20
|
||||
|
||||
|
@ -62,7 +62,7 @@ rustls = ["actix-tls/rustls", "awc/rustls", "rust-tls"]
|
||||
actix-codec = "0.2.0"
|
||||
actix-service = "1.0.1"
|
||||
actix-utils = "1.0.4"
|
||||
actix-router = "0.2.0"
|
||||
actix-router = "0.2.1"
|
||||
actix-rt = "1.0.0"
|
||||
actix-server = "1.0.0"
|
||||
actix-testing = "1.0.0"
|
||||
@ -115,4 +115,4 @@ actix-identity = { path = "actix-identity" }
|
||||
actix-session = { path = "actix-session" }
|
||||
actix-files = { path = "actix-files" }
|
||||
actix-multipart = { path = "actix-multipart" }
|
||||
awc = { path = "awc" }
|
||||
awc = { path = "awc" }
|
@ -814,7 +814,7 @@ where
|
||||
res
|
||||
}
|
||||
}
|
||||
.boxed_local(),
|
||||
.boxed_local(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ where
|
||||
service
|
||||
})
|
||||
}
|
||||
.boxed_local()
|
||||
.boxed_local()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,6 +154,6 @@ where
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
.boxed_local()
|
||||
.boxed_local()
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ where
|
||||
Err(err) => Ok(req.error_response(err)),
|
||||
}
|
||||
}
|
||||
.boxed_local()
|
||||
.boxed_local()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ where
|
||||
}
|
||||
})
|
||||
}
|
||||
.boxed_local()
|
||||
.boxed_local()
|
||||
}
|
||||
}
|
||||
|
||||
|
13
src/lib.rs
13
src/lib.rs
@ -151,12 +151,13 @@ pub mod dev {
|
||||
pub use actix_server::Server;
|
||||
pub use actix_service::{Service, Transform};
|
||||
|
||||
pub(crate) fn insert_slash(path: &str) -> String {
|
||||
let mut path = path.to_owned();
|
||||
if !path.is_empty() && !path.starts_with('/') {
|
||||
path.insert(0, '/');
|
||||
};
|
||||
path
|
||||
pub(crate) fn insert_slash(mut patterns: Vec<String>) -> Vec<String> {
|
||||
for path in &mut patterns {
|
||||
if !path.is_empty() && !path.starts_with('/') {
|
||||
path.insert(0, '/');
|
||||
};
|
||||
}
|
||||
patterns
|
||||
}
|
||||
|
||||
use crate::http::header::ContentEncoding;
|
||||
|
@ -150,7 +150,7 @@ where
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
.boxed_local()
|
||||
.boxed_local()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ where
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
.boxed_local()
|
||||
.boxed_local()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ use std::rc::Rc;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use actix_http::{Error, Extensions, Response};
|
||||
use actix_router::IntoPattern;
|
||||
use actix_service::boxed::{self, BoxService, BoxServiceFactory};
|
||||
use actix_service::{
|
||||
apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, Transform,
|
||||
@ -48,7 +49,7 @@ type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Err
|
||||
/// Default behavior could be overriden with `default_resource()` method.
|
||||
pub struct Resource<T = ResourceEndpoint> {
|
||||
endpoint: T,
|
||||
rdef: String,
|
||||
rdef: Vec<String>,
|
||||
name: Option<String>,
|
||||
routes: Vec<Route>,
|
||||
data: Option<Extensions>,
|
||||
@ -58,12 +59,12 @@ pub struct Resource<T = ResourceEndpoint> {
|
||||
}
|
||||
|
||||
impl Resource {
|
||||
pub fn new(path: &str) -> Resource {
|
||||
pub fn new<T: IntoPattern>(path: T) -> Resource {
|
||||
let fref = Rc::new(RefCell::new(None));
|
||||
|
||||
Resource {
|
||||
routes: Vec::new(),
|
||||
rdef: path.to_string(),
|
||||
rdef: path.patterns(),
|
||||
name: None,
|
||||
endpoint: ResourceEndpoint::new(fref.clone()),
|
||||
factory_ref: fref,
|
||||
@ -381,9 +382,9 @@ where
|
||||
Some(std::mem::replace(&mut self.guards, Vec::new()))
|
||||
};
|
||||
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
|
||||
ResourceDef::new(&insert_slash(&self.rdef))
|
||||
ResourceDef::new(insert_slash(self.rdef.clone()))
|
||||
} else {
|
||||
ResourceDef::new(&self.rdef)
|
||||
ResourceDef::new(self.rdef.clone())
|
||||
};
|
||||
if let Some(ref name) = self.name {
|
||||
*rdef.name_mut() = name.clone();
|
||||
@ -660,6 +661,23 @@ mod tests {
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_pattern() {
|
||||
let mut srv =
|
||||
init_service(App::new().service(web::resource(["/test", "/test2"]).to(|| {
|
||||
async {
|
||||
Ok::<_, Error>(HttpResponse::Ok())
|
||||
}
|
||||
})))
|
||||
.await;
|
||||
let req = TestRequest::with_uri("/test").to_request();
|
||||
let resp = call_service(&mut srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let req = TestRequest::with_uri("/test2").to_request();
|
||||
let resp = call_service(&mut srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_default_resource() {
|
||||
let mut srv = init_service(
|
||||
|
@ -8,7 +8,7 @@ use actix_http::{
|
||||
Error, Extensions, HttpMessage, Payload, PayloadStream, RequestHead, Response,
|
||||
ResponseHead,
|
||||
};
|
||||
use actix_router::{Path, Resource, ResourceDef, Url};
|
||||
use actix_router::{IntoPattern, Path, Resource, ResourceDef, Url};
|
||||
use actix_service::{IntoServiceFactory, ServiceFactory};
|
||||
|
||||
use crate::config::{AppConfig, AppService};
|
||||
@ -422,16 +422,16 @@ impl<B: MessageBody> fmt::Debug for ServiceResponse<B> {
|
||||
}
|
||||
|
||||
pub struct WebService {
|
||||
rdef: String,
|
||||
rdef: Vec<String>,
|
||||
name: Option<String>,
|
||||
guards: Vec<Box<dyn Guard>>,
|
||||
}
|
||||
|
||||
impl WebService {
|
||||
/// Create new `WebService` instance.
|
||||
pub fn new(path: &str) -> Self {
|
||||
pub fn new<T: IntoPattern>(path: T) -> Self {
|
||||
WebService {
|
||||
rdef: path.to_string(),
|
||||
rdef: path.patterns(),
|
||||
name: None,
|
||||
guards: Vec::new(),
|
||||
}
|
||||
@ -491,7 +491,7 @@ impl WebService {
|
||||
|
||||
struct WebServiceImpl<T> {
|
||||
srv: T,
|
||||
rdef: String,
|
||||
rdef: Vec<String>,
|
||||
name: Option<String>,
|
||||
guards: Vec<Box<dyn Guard>>,
|
||||
}
|
||||
@ -514,9 +514,9 @@ where
|
||||
};
|
||||
|
||||
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
|
||||
ResourceDef::new(&insert_slash(&self.rdef))
|
||||
ResourceDef::new(insert_slash(self.rdef))
|
||||
} else {
|
||||
ResourceDef::new(&self.rdef)
|
||||
ResourceDef::new(self.rdef)
|
||||
};
|
||||
if let Some(ref name) = self.name {
|
||||
*rdef.name_mut() = name.clone();
|
||||
|
@ -365,7 +365,7 @@ where
|
||||
.map_err(|_| UrlencodedError::Parse)
|
||||
}
|
||||
}
|
||||
.boxed_local(),
|
||||
.boxed_local(),
|
||||
);
|
||||
self.poll(cx)
|
||||
}
|
||||
|
@ -396,7 +396,7 @@ where
|
||||
}
|
||||
Ok(serde_json::from_slice::<U>(&body)?)
|
||||
}
|
||||
.boxed_local(),
|
||||
.boxed_local(),
|
||||
);
|
||||
|
||||
self.poll(cx)
|
||||
|
@ -229,7 +229,7 @@ impl FromRequest for String {
|
||||
.ok_or_else(|| ErrorBadRequest("Can not decode body"))?)
|
||||
}
|
||||
}
|
||||
.boxed_local(),
|
||||
.boxed_local(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -391,7 +391,7 @@ impl Future for HttpMessageBody {
|
||||
}
|
||||
Ok(body.freeze())
|
||||
}
|
||||
.boxed_local(),
|
||||
.boxed_local(),
|
||||
);
|
||||
self.poll(cx)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Essentials helper functions and types for application registration.
|
||||
use actix_http::http::Method;
|
||||
use actix_router::IntoPattern;
|
||||
use futures::Future;
|
||||
|
||||
pub use actix_http::Response as HttpResponse;
|
||||
@ -50,7 +51,7 @@ pub use crate::types::*;
|
||||
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
|
||||
/// );
|
||||
/// ```
|
||||
pub fn resource(path: &str) -> Resource {
|
||||
pub fn resource<T: IntoPattern>(path: T) -> Resource {
|
||||
Resource::new(path)
|
||||
}
|
||||
|
||||
@ -249,7 +250,7 @@ where
|
||||
/// .finish(my_service)
|
||||
/// );
|
||||
/// ```
|
||||
pub fn service(path: &str) -> WebService {
|
||||
pub fn service<T: IntoPattern>(path: T) -> WebService {
|
||||
WebService::new(path)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user