1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-07-01 00:44:26 +02:00

update to router 0.5.0 beta (#2339)

This commit is contained in:
Rob Ede
2021-08-06 22:42:31 +01:00
committed by GitHub
parent 293c52c3ef
commit f6e69919ed
24 changed files with 4063 additions and 57 deletions

View File

@ -334,7 +334,7 @@ where
U: AsRef<str>,
{
let mut rdef = ResourceDef::new(url.as_ref());
*rdef.name_mut() = name.as_ref().to_string();
rdef.set_name(name.as_ref());
self.external.push(rdef);
self
}

View File

@ -291,7 +291,7 @@ impl Service<ServiceRequest> for AppRouting {
actix_service::always_ready!();
fn call(&self, mut req: ServiceRequest) -> Self::Future {
let res = self.router.recognize_checked(&mut req, |req, guards| {
let res = self.router.recognize_fn(&mut req, |req, guards| {
if let Some(ref guards) = guards {
for f in guards {
if !f.check(req.head()) {

View File

@ -249,7 +249,7 @@ impl ServiceConfig {
U: AsRef<str>,
{
let mut rdef = ResourceDef::new(url.as_ref());
*rdef.name_mut() = name.as_ref().to_string();
rdef.set_name(name.as_ref());
self.external.push(rdef);
self
}

View File

@ -28,11 +28,22 @@ pub use actix_service::{
use crate::http::header::ContentEncoding;
use actix_http::{Response, ResponseBuilder};
pub(crate) fn insert_leading_slash(mut patterns: Vec<String>) -> Vec<String> {
for path in &mut patterns {
if !path.is_empty() && !path.starts_with('/') {
path.insert(0, '/');
};
use actix_router::Patterns;
pub(crate) fn ensure_leading_slash(mut patterns: Patterns) -> Patterns {
match &mut patterns {
Patterns::Single(pat) => {
if !pat.is_empty() && !pat.starts_with('/') {
pat.insert(0, '/');
};
}
Patterns::List(pats) => {
for pat in pats {
if !pat.is_empty() && !pat.starts_with('/') {
pat.insert(0, '/');
};
}
}
}
patterns

View File

@ -509,7 +509,7 @@ mod tests {
#[test]
fn test_url_for() {
let mut res = ResourceDef::new("/user/{name}.{ext}");
*res.name_mut() = "index".to_string();
res.set_name("index");
let mut rmap = ResourceMap::new(ResourceDef::new(""));
rmap.add(&mut res, None);
@ -539,7 +539,7 @@ mod tests {
#[test]
fn test_url_for_static() {
let mut rdef = ResourceDef::new("/index.html");
*rdef.name_mut() = "index".to_string();
rdef.set_name("index");
let mut rmap = ResourceMap::new(ResourceDef::new(""));
rmap.add(&mut rdef, None);
@ -560,7 +560,7 @@ mod tests {
#[test]
fn test_match_name() {
let mut rdef = ResourceDef::new("/index.html");
*rdef.name_mut() = "index".to_string();
rdef.set_name("index");
let mut rmap = ResourceMap::new(ResourceDef::new(""));
rmap.add(&mut rdef, None);
@ -579,7 +579,7 @@ mod tests {
fn test_url_for_external() {
let mut rdef = ResourceDef::new("https://youtube.com/watch/{video_id}");
*rdef.name_mut() = "youtube".to_string();
rdef.set_name("youtube");
let mut rmap = ResourceMap::new(ResourceDef::new(""));
rmap.add(&mut rdef, None);

View File

@ -4,7 +4,7 @@ use std::future::Future;
use std::rc::Rc;
use actix_http::Extensions;
use actix_router::IntoPattern;
use actix_router::{IntoPatterns, Patterns};
use actix_service::boxed::{self, BoxService, BoxServiceFactory};
use actix_service::{
apply, apply_fn_factory, fn_service, IntoServiceFactory, Service, ServiceFactory,
@ -15,7 +15,7 @@ use futures_util::future::join_all;
use crate::{
data::Data,
dev::{insert_leading_slash, AppService, HttpServiceFactory, ResourceDef},
dev::{ensure_leading_slash, AppService, HttpServiceFactory, ResourceDef},
guard::Guard,
handler::Handler,
responder::Responder,
@ -51,7 +51,7 @@ type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Err
/// Default behavior could be overridden with `default_resource()` method.
pub struct Resource<T = ResourceEndpoint> {
endpoint: T,
rdef: Vec<String>,
rdef: Patterns,
name: Option<String>,
routes: Vec<Route>,
app_data: Option<Extensions>,
@ -61,7 +61,7 @@ pub struct Resource<T = ResourceEndpoint> {
}
impl Resource {
pub fn new<T: IntoPattern>(path: T) -> Resource {
pub fn new<T: IntoPatterns>(path: T) -> Resource {
let fref = Rc::new(RefCell::new(None));
Resource {
@ -391,13 +391,13 @@ where
};
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
ResourceDef::new(insert_leading_slash(self.rdef.clone()))
ResourceDef::new(ensure_leading_slash(self.rdef.clone()))
} else {
ResourceDef::new(self.rdef.clone())
};
if let Some(ref name) = self.name {
*rdef.name_mut() = name.clone();
rdef.set_name(name);
}
*self.factory_ref.borrow_mut() = Some(ResourceFactory {

View File

@ -29,9 +29,8 @@ impl ResourceMap {
pub fn add(&mut self, pattern: &mut ResourceDef, nested: Option<Rc<ResourceMap>>) {
pattern.set_id(self.patterns.len() as u16);
self.patterns.push((pattern.clone(), nested));
if !pattern.name().is_empty() {
self.named
.insert(pattern.name().to_string(), pattern.clone());
if let Some(name) = pattern.name() {
self.named.insert(name.to_owned(), pattern.clone());
}
}
@ -83,10 +82,10 @@ impl ResourceMap {
for (pattern, rmap) in &self.patterns {
if let Some(ref rmap) = rmap {
if let Some(plen) = pattern.is_prefix_match(path) {
return rmap.has_resource(&path[plen..]);
if let Some(pat_len) = pattern.find_match(path) {
return rmap.has_resource(&path[pat_len..]);
}
} else if pattern.is_match(path) || pattern.pattern() == "" && path == "/" {
} else if pattern.is_match(path) || pattern.pattern() == Some("") && path == "/" {
return true;
}
}
@ -100,14 +99,11 @@ impl ResourceMap {
for (pattern, rmap) in &self.patterns {
if let Some(ref rmap) = rmap {
if let Some(plen) = pattern.is_prefix_match(path) {
if let Some(plen) = pattern.find_match(path) {
return rmap.match_name(&path[plen..]);
}
} else if pattern.is_match(path) {
return match pattern.name() {
"" => None,
s => Some(s),
};
return pattern.name();
}
}
@ -136,8 +132,9 @@ impl ResourceMap {
fn traverse_resource_pattern(&self, remaining: &str) -> String {
for (pattern, rmap) in &self.patterns {
if let Some(ref rmap) = rmap {
if let Some(prefix_len) = pattern.is_prefix_match(remaining) {
let prefix = pattern.pattern().to_owned();
if let Some(prefix_len) = pattern.find_match(remaining) {
// TODO: think about unwrap_or
let prefix = pattern.pattern().unwrap_or("").to_owned();
return [
prefix,
@ -146,7 +143,8 @@ impl ResourceMap {
.concat();
}
} else if pattern.is_match(remaining) {
return pattern.pattern().to_owned();
// TODO: think about unwrap_or
return pattern.pattern().unwrap_or("").to_owned();
}
}
@ -181,10 +179,15 @@ impl ResourceMap {
I: AsRef<str>,
{
if let Some(pattern) = self.named.get(name) {
if pattern.pattern().starts_with('/') {
if pattern
.pattern()
.map(|pat| pat.starts_with('/'))
.unwrap_or(false)
{
self.fill_root(path, elements)?;
}
if pattern.resource_path(path, elements) {
if pattern.resource_path_from_iter(path, elements) {
Ok(Some(()))
} else {
Err(UrlGenerationError::NotEnoughElements)
@ -213,7 +216,8 @@ impl ResourceMap {
if let Some(ref parent) = self.parent.borrow().upgrade() {
parent.fill_root(path, elements)?;
}
if self.root.resource_path(path, elements) {
if self.root.resource_path_from_iter(path, elements) {
Ok(())
} else {
Err(UrlGenerationError::NotEnoughElements)
@ -233,7 +237,7 @@ impl ResourceMap {
if let Some(ref parent) = self.parent.borrow().upgrade() {
if let Some(pattern) = parent.named.get(name) {
self.fill_root(path, elements)?;
if pattern.resource_path(path, elements) {
if pattern.resource_path_from_iter(path, elements) {
Ok(Some(()))
} else {
Err(UrlGenerationError::NotEnoughElements)
@ -329,7 +333,7 @@ mod tests {
let mut root = ResourceMap::new(ResourceDef::root_prefix(""));
let mut rdef = ResourceDef::new("/info");
*rdef.name_mut() = "root_info".to_owned();
rdef.set_name("root_info");
root.add(&mut rdef, None);
let mut user_map = ResourceMap::new(ResourceDef::root_prefix(""));
@ -337,7 +341,7 @@ mod tests {
user_map.add(&mut rdef, None);
let mut rdef = ResourceDef::new("/post/{post_id}");
*rdef.name_mut() = "user_post".to_owned();
rdef.set_name("user_post");
user_map.add(&mut rdef, None);
root.add(

View File

@ -530,7 +530,7 @@ impl Service<ServiceRequest> for ScopeService {
actix_service::always_ready!();
fn call(&self, mut req: ServiceRequest) -> Self::Future {
let res = self.router.recognize_checked(&mut req, |req, guards| {
let res = self.router.recognize_fn(&mut req, |req, guards| {
if let Some(ref guards) = guards {
for f in guards {
if !f.check(req.head()) {

View File

@ -7,14 +7,14 @@ use actix_http::{
http::{HeaderMap, Method, StatusCode, Uri, Version},
Extensions, HttpMessage, Payload, PayloadStream, RequestHead, Response, ResponseHead,
};
use actix_router::{IntoPattern, Path, Resource, ResourceDef, Url};
use actix_router::{IntoPatterns, Path, Patterns, Resource, ResourceDef, Url};
use actix_service::{IntoServiceFactory, ServiceFactory};
#[cfg(feature = "cookies")]
use cookie::{Cookie, ParseError as CookieParseError};
use crate::{
config::{AppConfig, AppService},
dev::insert_leading_slash,
dev::ensure_leading_slash,
guard::Guard,
info::ConnectionInfo,
rmap::ResourceMap,
@ -212,14 +212,14 @@ impl ServiceRequest {
self.req.match_pattern()
}
#[inline]
/// Get a mutable reference to the Path parameters.
#[inline]
pub fn match_info_mut(&mut self) -> &mut Path<Url> {
self.req.match_info_mut()
}
#[inline]
/// Get a reference to a `ResourceMap` of current application.
#[inline]
pub fn resource_map(&self) -> &ResourceMap {
self.req.resource_map()
}
@ -459,14 +459,14 @@ where
}
pub struct WebService {
rdef: Vec<String>,
rdef: Patterns,
name: Option<String>,
guards: Vec<Box<dyn Guard>>,
}
impl WebService {
/// Create new `WebService` instance.
pub fn new<T: IntoPattern>(path: T) -> Self {
pub fn new<T: IntoPatterns>(path: T) -> Self {
WebService {
rdef: path.patterns(),
name: None,
@ -528,7 +528,7 @@ impl WebService {
struct WebServiceImpl<T> {
srv: T,
rdef: Vec<String>,
rdef: Patterns,
name: Option<String>,
guards: Vec<Box<dyn Guard>>,
}
@ -551,13 +551,15 @@ where
};
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
ResourceDef::new(insert_leading_slash(self.rdef))
ResourceDef::new(ensure_leading_slash(self.rdef))
} else {
ResourceDef::new(self.rdef)
};
if let Some(ref name) = self.name {
*rdef.name_mut() = name.clone();
rdef.set_name(name);
}
config.register_service(rdef, guards, self.srv, None)
}
}

View File

@ -209,7 +209,7 @@ mod tests {
let resource = ResourceDef::new("/{value}/");
let mut req = TestRequest::with_uri("/32/").to_srv_request();
resource.match_path(req.match_info_mut());
resource.capture_match_info(req.match_info_mut());
let (req, mut pl) = req.into_parts();
assert_eq!(*Path::<i8>::from_request(&req, &mut pl).await.unwrap(), 32);
@ -221,7 +221,7 @@ mod tests {
let resource = ResourceDef::new("/{key}/{value}/");
let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
resource.match_path(req.match_info_mut());
resource.capture_match_info(req.match_info_mut());
let (req, mut pl) = req.into_parts();
let (Path(res),) = <(Path<(String, String)>,)>::from_request(&req, &mut pl)
@ -247,7 +247,7 @@ mod tests {
let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
let resource = ResourceDef::new("/{key}/{value}/");
resource.match_path(req.match_info_mut());
resource.capture_match_info(req.match_info_mut());
let (req, mut pl) = req.into_parts();
let mut s = Path::<MyStruct>::from_request(&req, &mut pl).await.unwrap();
@ -270,7 +270,7 @@ mod tests {
let mut req = TestRequest::with_uri("/name/32/").to_srv_request();
let resource = ResourceDef::new("/{key}/{value}/");
resource.match_path(req.match_info_mut());
resource.capture_match_info(req.match_info_mut());
let (req, mut pl) = req.into_parts();
let s = Path::<Test2>::from_request(&req, &mut pl).await.unwrap();

View File

@ -1,10 +1,10 @@
//! Essentials helper functions and types for application registration.
use actix_http::http::Method;
use actix_router::IntoPattern;
use std::future::Future;
use actix_http::http::Method;
pub use actix_http::Response as HttpResponse;
use actix_router::IntoPatterns;
pub use bytes::{Buf, BufMut, Bytes, BytesMut};
use crate::error::BlockingError;
@ -51,7 +51,7 @@ pub use crate::types::*;
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
/// );
/// ```
pub fn resource<T: IntoPattern>(path: T) -> Resource {
pub fn resource<T: IntoPatterns>(path: T) -> Resource {
Resource::new(path)
}
@ -268,7 +268,7 @@ where
/// .finish(my_service)
/// );
/// ```
pub fn service<T: IntoPattern>(path: T) -> WebService {
pub fn service<T: IntoPatterns>(path: T) -> WebService {
WebService::new(path)
}