mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-27 17:22:57 +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 gracefully stop test server via `TestServer::stop()`
|
||||||
|
|
||||||
|
* Allow to specify multi-patterns for resources
|
||||||
|
|
||||||
## [2.0.0-rc] - 2019-12-20
|
## [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-codec = "0.2.0"
|
||||||
actix-service = "1.0.1"
|
actix-service = "1.0.1"
|
||||||
actix-utils = "1.0.4"
|
actix-utils = "1.0.4"
|
||||||
actix-router = "0.2.0"
|
actix-router = "0.2.1"
|
||||||
actix-rt = "1.0.0"
|
actix-rt = "1.0.0"
|
||||||
actix-server = "1.0.0"
|
actix-server = "1.0.0"
|
||||||
actix-testing = "1.0.0"
|
actix-testing = "1.0.0"
|
||||||
|
@ -151,12 +151,13 @@ pub mod dev {
|
|||||||
pub use actix_server::Server;
|
pub use actix_server::Server;
|
||||||
pub use actix_service::{Service, Transform};
|
pub use actix_service::{Service, Transform};
|
||||||
|
|
||||||
pub(crate) fn insert_slash(path: &str) -> String {
|
pub(crate) fn insert_slash(mut patterns: Vec<String>) -> Vec<String> {
|
||||||
let mut path = path.to_owned();
|
for path in &mut patterns {
|
||||||
if !path.is_empty() && !path.starts_with('/') {
|
if !path.is_empty() && !path.starts_with('/') {
|
||||||
path.insert(0, '/');
|
path.insert(0, '/');
|
||||||
};
|
};
|
||||||
path
|
}
|
||||||
|
patterns
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::http::header::ContentEncoding;
|
use crate::http::header::ContentEncoding;
|
||||||
|
@ -6,6 +6,7 @@ use std::rc::Rc;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_http::{Error, Extensions, Response};
|
use actix_http::{Error, Extensions, Response};
|
||||||
|
use actix_router::IntoPattern;
|
||||||
use actix_service::boxed::{self, BoxService, BoxServiceFactory};
|
use actix_service::boxed::{self, BoxService, BoxServiceFactory};
|
||||||
use actix_service::{
|
use actix_service::{
|
||||||
apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, Transform,
|
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.
|
/// Default behavior could be overriden with `default_resource()` method.
|
||||||
pub struct Resource<T = ResourceEndpoint> {
|
pub struct Resource<T = ResourceEndpoint> {
|
||||||
endpoint: T,
|
endpoint: T,
|
||||||
rdef: String,
|
rdef: Vec<String>,
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
routes: Vec<Route>,
|
routes: Vec<Route>,
|
||||||
data: Option<Extensions>,
|
data: Option<Extensions>,
|
||||||
@ -58,12 +59,12 @@ pub struct Resource<T = ResourceEndpoint> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Resource {
|
impl Resource {
|
||||||
pub fn new(path: &str) -> Resource {
|
pub fn new<T: IntoPattern>(path: T) -> Resource {
|
||||||
let fref = Rc::new(RefCell::new(None));
|
let fref = Rc::new(RefCell::new(None));
|
||||||
|
|
||||||
Resource {
|
Resource {
|
||||||
routes: Vec::new(),
|
routes: Vec::new(),
|
||||||
rdef: path.to_string(),
|
rdef: path.patterns(),
|
||||||
name: None,
|
name: None,
|
||||||
endpoint: ResourceEndpoint::new(fref.clone()),
|
endpoint: ResourceEndpoint::new(fref.clone()),
|
||||||
factory_ref: fref,
|
factory_ref: fref,
|
||||||
@ -381,9 +382,9 @@ where
|
|||||||
Some(std::mem::replace(&mut self.guards, Vec::new()))
|
Some(std::mem::replace(&mut self.guards, Vec::new()))
|
||||||
};
|
};
|
||||||
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
|
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 {
|
} else {
|
||||||
ResourceDef::new(&self.rdef)
|
ResourceDef::new(self.rdef.clone())
|
||||||
};
|
};
|
||||||
if let Some(ref name) = self.name {
|
if let Some(ref name) = self.name {
|
||||||
*rdef.name_mut() = name.clone();
|
*rdef.name_mut() = name.clone();
|
||||||
@ -660,6 +661,23 @@ mod tests {
|
|||||||
assert_eq!(resp.status(), StatusCode::OK);
|
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]
|
#[actix_rt::test]
|
||||||
async fn test_default_resource() {
|
async fn test_default_resource() {
|
||||||
let mut srv = init_service(
|
let mut srv = init_service(
|
||||||
|
@ -8,7 +8,7 @@ use actix_http::{
|
|||||||
Error, Extensions, HttpMessage, Payload, PayloadStream, RequestHead, Response,
|
Error, Extensions, HttpMessage, Payload, PayloadStream, RequestHead, Response,
|
||||||
ResponseHead,
|
ResponseHead,
|
||||||
};
|
};
|
||||||
use actix_router::{Path, Resource, ResourceDef, Url};
|
use actix_router::{IntoPattern, Path, Resource, ResourceDef, Url};
|
||||||
use actix_service::{IntoServiceFactory, ServiceFactory};
|
use actix_service::{IntoServiceFactory, ServiceFactory};
|
||||||
|
|
||||||
use crate::config::{AppConfig, AppService};
|
use crate::config::{AppConfig, AppService};
|
||||||
@ -422,16 +422,16 @@ impl<B: MessageBody> fmt::Debug for ServiceResponse<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct WebService {
|
pub struct WebService {
|
||||||
rdef: String,
|
rdef: Vec<String>,
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
guards: Vec<Box<dyn Guard>>,
|
guards: Vec<Box<dyn Guard>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebService {
|
impl WebService {
|
||||||
/// Create new `WebService` instance.
|
/// Create new `WebService` instance.
|
||||||
pub fn new(path: &str) -> Self {
|
pub fn new<T: IntoPattern>(path: T) -> Self {
|
||||||
WebService {
|
WebService {
|
||||||
rdef: path.to_string(),
|
rdef: path.patterns(),
|
||||||
name: None,
|
name: None,
|
||||||
guards: Vec::new(),
|
guards: Vec::new(),
|
||||||
}
|
}
|
||||||
@ -491,7 +491,7 @@ impl WebService {
|
|||||||
|
|
||||||
struct WebServiceImpl<T> {
|
struct WebServiceImpl<T> {
|
||||||
srv: T,
|
srv: T,
|
||||||
rdef: String,
|
rdef: Vec<String>,
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
guards: Vec<Box<dyn Guard>>,
|
guards: Vec<Box<dyn Guard>>,
|
||||||
}
|
}
|
||||||
@ -514,9 +514,9 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
|
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
|
||||||
ResourceDef::new(&insert_slash(&self.rdef))
|
ResourceDef::new(insert_slash(self.rdef))
|
||||||
} else {
|
} else {
|
||||||
ResourceDef::new(&self.rdef)
|
ResourceDef::new(self.rdef)
|
||||||
};
|
};
|
||||||
if let Some(ref name) = self.name {
|
if let Some(ref name) = self.name {
|
||||||
*rdef.name_mut() = name.clone();
|
*rdef.name_mut() = name.clone();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! Essentials helper functions and types for application registration.
|
//! Essentials helper functions and types for application registration.
|
||||||
use actix_http::http::Method;
|
use actix_http::http::Method;
|
||||||
|
use actix_router::IntoPattern;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
|
|
||||||
pub use actix_http::Response as HttpResponse;
|
pub use actix_http::Response as HttpResponse;
|
||||||
@ -50,7 +51,7 @@ pub use crate::types::*;
|
|||||||
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
|
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn resource(path: &str) -> Resource {
|
pub fn resource<T: IntoPattern>(path: T) -> Resource {
|
||||||
Resource::new(path)
|
Resource::new(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +250,7 @@ where
|
|||||||
/// .finish(my_service)
|
/// .finish(my_service)
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn service(path: &str) -> WebService {
|
pub fn service<T: IntoPattern>(path: T) -> WebService {
|
||||||
WebService::new(path)
|
WebService::new(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user