@@ -15,20 +15,21 @@ use crate::errors::ToErrorValue;
15
15
use crate :: errors:: { ErrorType , ErrorTypeDefaults , ValError , ValResult } ;
16
16
use crate :: input:: downcast_python_input;
17
17
use crate :: input:: Input ;
18
+ use crate :: input:: ValidationMatch ;
18
19
use crate :: tools:: SchemaDict ;
19
- use crate :: url:: { schema_is_special , PyMultiHostUrl , PyUrl } ;
20
+ use crate :: url:: { scheme_is_special , PyMultiHostUrl , PyUrl } ;
20
21
21
22
use super :: literal:: expected_repr_name;
22
23
use super :: Exactness ;
23
24
use super :: { BuildValidator , CombinedValidator , DefinitionsBuilder , ValidationState , Validator } ;
24
25
25
- type AllowedSchemas = Option < ( AHashSet < String > , String ) > ;
26
+ type AllowedSchemes = Option < ( AHashSet < String > , String ) > ;
26
27
27
28
#[ derive( Debug , Clone ) ]
28
29
pub struct UrlValidator {
29
30
strict : bool ,
30
31
max_length : Option < usize > ,
31
- allowed_schemes : AllowedSchemas ,
32
+ allowed_schemes : AllowedSchemes ,
32
33
host_required : bool ,
33
34
default_host : Option < String > ,
34
35
default_port : Option < u16 > ,
@@ -44,7 +45,7 @@ impl BuildValidator for UrlValidator {
44
45
config : Option < & Bound < ' _ , PyDict > > ,
45
46
_definitions : & mut DefinitionsBuilder < CombinedValidator > ,
46
47
) -> PyResult < CombinedValidator > {
47
- let ( allowed_schemes, name) = get_allowed_schemas ( schema, Self :: EXPECTED_TYPE ) ?;
48
+ let ( allowed_schemes, name) = get_allowed_schemes ( schema, Self :: EXPECTED_TYPE ) ?;
48
49
49
50
Ok ( Self {
50
51
strict : is_strict ( schema, config) ?,
@@ -107,31 +108,23 @@ impl Validator for UrlValidator {
107
108
108
109
impl UrlValidator {
109
110
fn get_url < ' py > ( & self , input : & ( impl Input < ' py > + ?Sized ) , strict : bool ) -> ValResult < EitherUrl < ' py > > {
110
- match input. validate_str ( strict, false ) {
111
- Ok ( val_match) => {
112
- let either_str = val_match. into_inner ( ) ;
113
- let cow = either_str. as_cow ( ) ?;
114
- let url_str = cow. as_ref ( ) ;
115
-
116
- self . check_length ( input, url_str) ?;
117
-
118
- parse_url ( url_str, input, strict) . map ( EitherUrl :: Rust )
119
- }
120
- Err ( _) => {
121
- // we don't need to worry about whether the url was parsed in strict mode before,
122
- // even if it was, any syntax errors would have been fixed by the first validation
123
- if let Some ( py_url) = downcast_python_input :: < PyUrl > ( input) {
124
- self . check_length ( input, py_url. get ( ) . url ( ) . as_str ( ) ) ?;
125
- Ok ( EitherUrl :: Py ( py_url. clone ( ) ) )
126
- } else if let Some ( multi_host_url) = downcast_python_input :: < PyMultiHostUrl > ( input) {
127
- let url_str = multi_host_url. get ( ) . __str__ ( ) ;
128
- self . check_length ( input, & url_str) ?;
129
-
130
- parse_url ( & url_str, input, strict) . map ( EitherUrl :: Rust )
131
- } else {
132
- Err ( ValError :: new ( ErrorTypeDefaults :: UrlType , input) )
133
- }
134
- }
111
+ if let Some ( py_url) = downcast_python_input :: < PyUrl > ( input) {
112
+ // we don't need to worry about whether the url was parsed in strict mode before,
113
+ // even if it was, any syntax errors would have been fixed by the first validation
114
+ self . check_length ( input, py_url. get ( ) . url ( ) . as_str ( ) ) ?;
115
+ Ok ( EitherUrl :: Py ( py_url. clone ( ) ) )
116
+ } else if let Some ( multi_host_url) = downcast_python_input :: < PyMultiHostUrl > ( input) {
117
+ let url_str = multi_host_url. get ( ) . __str__ ( ) ;
118
+ self . check_length ( input, & url_str) ?;
119
+ parse_url ( & url_str, input, strict) . map ( EitherUrl :: Rust )
120
+ } else if let Ok ( either_str) = input. validate_str ( strict, false ) . map ( ValidationMatch :: into_inner) {
121
+ let cow = either_str. as_cow ( ) ?;
122
+ let url_str = cow. as_ref ( ) ;
123
+
124
+ self . check_length ( input, url_str) ?;
125
+ parse_url ( url_str, input, strict) . map ( EitherUrl :: Rust )
126
+ } else {
127
+ Err ( ValError :: new ( ErrorTypeDefaults :: UrlType , input) )
135
128
}
136
129
}
137
130
@@ -192,7 +185,7 @@ impl CopyFromPyUrl for EitherUrl<'_> {
192
185
pub struct MultiHostUrlValidator {
193
186
strict : bool ,
194
187
max_length : Option < usize > ,
195
- allowed_schemes : AllowedSchemas ,
188
+ allowed_schemes : AllowedSchemes ,
196
189
host_required : bool ,
197
190
default_host : Option < String > ,
198
191
default_port : Option < u16 > ,
@@ -208,7 +201,7 @@ impl BuildValidator for MultiHostUrlValidator {
208
201
config : Option < & Bound < ' _ , PyDict > > ,
209
202
_definitions : & mut DefinitionsBuilder < CombinedValidator > ,
210
203
) -> PyResult < CombinedValidator > {
211
- let ( allowed_schemes, name) = get_allowed_schemas ( schema, Self :: EXPECTED_TYPE ) ?;
204
+ let ( allowed_schemes, name) = get_allowed_schemes ( schema, Self :: EXPECTED_TYPE ) ?;
212
205
213
206
let default_host: Option < String > = schema. get_as ( intern ! ( schema. py( ) , "default_host" ) ) ?;
214
207
if let Some ( ref default_host) = default_host {
@@ -276,32 +269,26 @@ impl Validator for MultiHostUrlValidator {
276
269
277
270
impl MultiHostUrlValidator {
278
271
fn get_url < ' py > ( & self , input : & ( impl Input < ' py > + ?Sized ) , strict : bool ) -> ValResult < EitherMultiHostUrl < ' py > > {
279
- match input. validate_str ( strict, false ) {
280
- Ok ( val_match) => {
281
- let either_str = val_match. into_inner ( ) ;
282
- let cow = either_str. as_cow ( ) ?;
283
- let url_str = cow. as_ref ( ) ;
284
-
285
- self . check_length ( input, || url_str. len ( ) ) ?;
286
-
287
- parse_multihost_url ( url_str, input, strict) . map ( EitherMultiHostUrl :: Rust )
288
- }
289
- Err ( _) => {
290
- // we don't need to worry about whether the url was parsed in strict mode before,
291
- // even if it was, any syntax errors would have been fixed by the first validation
292
- if let Some ( multi_url) = downcast_python_input :: < PyMultiHostUrl > ( input) {
293
- self . check_length ( input, || multi_url. get ( ) . __str__ ( ) . len ( ) ) ?;
294
- Ok ( EitherMultiHostUrl :: Py ( multi_url. clone ( ) ) )
295
- } else if let Some ( py_url) = downcast_python_input :: < PyUrl > ( input) {
296
- self . check_length ( input, || py_url. get ( ) . url ( ) . as_str ( ) . len ( ) ) ?;
297
- Ok ( EitherMultiHostUrl :: Rust ( PyMultiHostUrl :: new (
298
- py_url. get ( ) . url ( ) . clone ( ) ,
299
- None ,
300
- ) ) )
301
- } else {
302
- Err ( ValError :: new ( ErrorTypeDefaults :: UrlType , input) )
303
- }
304
- }
272
+ // we don't need to worry about whether the url was parsed in strict mode before,
273
+ // even if it was, any syntax errors would have been fixed by the first validation
274
+ if let Some ( multi_url) = downcast_python_input :: < PyMultiHostUrl > ( input) {
275
+ self . check_length ( input, || multi_url. get ( ) . __str__ ( ) . len ( ) ) ?;
276
+ Ok ( EitherMultiHostUrl :: Py ( multi_url. clone ( ) ) )
277
+ } else if let Some ( py_url) = downcast_python_input :: < PyUrl > ( input) {
278
+ self . check_length ( input, || py_url. get ( ) . url ( ) . as_str ( ) . len ( ) ) ?;
279
+ Ok ( EitherMultiHostUrl :: Rust ( PyMultiHostUrl :: new (
280
+ py_url. get ( ) . url ( ) . clone ( ) ,
281
+ None ,
282
+ ) ) )
283
+ } else if let Ok ( either_str) = input. validate_str ( strict, false ) . map ( ValidationMatch :: into_inner) {
284
+ let cow = either_str. as_cow ( ) ?;
285
+ let url_str = cow. as_ref ( ) ;
286
+
287
+ self . check_length ( input, || url_str. len ( ) ) ?;
288
+
289
+ parse_multihost_url ( url_str, input, strict) . map ( EitherMultiHostUrl :: Rust )
290
+ } else {
291
+ Err ( ValError :: new ( ErrorTypeDefaults :: UrlType , input) )
305
292
}
306
293
}
307
294
@@ -399,24 +386,24 @@ fn parse_multihost_url<'py>(
399
386
}
400
387
}
401
388
402
- // consume the url schema , some logic from `parse_scheme`
389
+ // consume the url scheme , some logic from `parse_scheme`
403
390
// https://github.com/servo/rust-url/blob/v2.3.1/url/src/parser.rs#L387-L411
404
- let schema_start = chars. position ;
405
- let schema_end = loop {
391
+ let scheme_start = chars. position ;
392
+ let scheme_end = loop {
406
393
match chars. next ( ) {
407
394
Some ( 'a' ..='z' | 'A' ..='Z' | '0' ..='9' | '+' | '-' | '.' ) => continue ,
408
395
Some ( ':' ) => {
409
- // require the schema to be non-empty
410
- let schema_end = chars. position - ':' . len_utf8 ( ) ;
411
- if schema_end > schema_start {
412
- break schema_end ;
396
+ // require the scheme to be non-empty
397
+ let scheme_end = chars. position - ':' . len_utf8 ( ) ;
398
+ if scheme_end > scheme_start {
399
+ break scheme_end ;
413
400
}
414
401
}
415
402
_ => { }
416
403
}
417
404
return parsing_err ! ( ParseError :: RelativeUrlWithoutBase ) ;
418
405
} ;
419
- let schema = url_str[ schema_start..schema_end ] . to_ascii_lowercase ( ) ;
406
+ let scheme = url_str[ scheme_start..scheme_end ] . to_ascii_lowercase ( ) ;
420
407
421
408
// consume the double slash, or any number of slashes, including backslashes, taken from `parse_with_scheme`
422
409
// https://github.com/servo/rust-url/blob/v2.3.1/url/src/parser.rs#L413-L456
@@ -437,7 +424,7 @@ fn parse_multihost_url<'py>(
437
424
let mut start = chars. position ;
438
425
while let Some ( c) = chars. next ( ) {
439
426
match c {
440
- '\\' if schema_is_special ( & schema ) => break ,
427
+ '\\' if scheme_is_special ( & scheme ) => break ,
441
428
'/' | '?' | '#' => break ,
442
429
',' => {
443
430
// minus 1 because we know that the last char was a `,` with length 1
@@ -587,7 +574,7 @@ trait CopyFromPyUrl {
587
574
fn url_mut ( & mut self ) -> & mut Url ;
588
575
}
589
576
590
- fn get_allowed_schemas ( schema : & Bound < ' _ , PyDict > , name : & ' static str ) -> PyResult < ( AllowedSchemas , String ) > {
577
+ fn get_allowed_schemes ( schema : & Bound < ' _ , PyDict > , name : & ' static str ) -> PyResult < ( AllowedSchemes , String ) > {
591
578
match schema. get_as :: < Bound < ' _ , PyList > > ( intern ! ( schema. py( ) , "allowed_schemes" ) ) ? {
592
579
Some ( list) => {
593
580
if list. is_empty ( ) {
0 commit comments