@@ -117,7 +117,7 @@ pub extern crate percent_encoding;
117
117
use encoding:: EncodingOverride ;
118
118
#[ cfg( feature = "heapsize" ) ] use heapsize:: HeapSizeOf ;
119
119
use host:: HostInternal ;
120
- use parser:: { Parser , Context , SchemeType , to_u32} ;
120
+ use parser:: { Parser , Context , SchemeType , to_u32, ViolationFn } ;
121
121
use percent_encoding:: { PATH_SEGMENT_ENCODE_SET , USERINFO_ENCODE_SET ,
122
122
percent_encode, percent_decode, utf8_percent_encode} ;
123
123
use std:: borrow:: Borrow ;
@@ -135,7 +135,7 @@ use std::str;
135
135
pub use origin:: { Origin , OpaqueOrigin } ;
136
136
pub use host:: { Host , HostAndPort , SocketAddrs } ;
137
137
pub use path_segments:: PathSegmentsMut ;
138
- pub use parser:: ParseError ;
138
+ pub use parser:: { ParseError , SyntaxViolation } ;
139
139
pub use slicing:: Position ;
140
140
141
141
mod encoding;
@@ -186,7 +186,7 @@ impl HeapSizeOf for Url {
186
186
pub struct ParseOptions < ' a > {
187
187
base_url : Option < & ' a Url > ,
188
188
encoding_override : encoding:: EncodingOverride ,
189
- log_syntax_violation : Option < & ' a Fn ( & ' static str ) > ,
189
+ violation_fn : ViolationFn < ' a > ,
190
190
}
191
191
192
192
impl < ' a > ParseOptions < ' a > {
@@ -209,9 +209,47 @@ impl<'a> ParseOptions<'a> {
209
209
self
210
210
}
211
211
212
- /// Call the provided function or closure on non-fatal parse errors.
212
+ /// Call the provided function or closure on non-fatal parse errors, passing
213
+ /// a static string description. This method is deprecated in favor of
214
+ /// `syntax_violation_callback` and is implemented as an adaptor for the
215
+ /// latter, passing the `SyntaxViolation` description. Only the last value
216
+ /// passed to either method will be used by a parser.
217
+ #[ deprecated]
213
218
pub fn log_syntax_violation ( mut self , new : Option < & ' a Fn ( & ' static str ) > ) -> Self {
214
- self . log_syntax_violation = new;
219
+ self . violation_fn = match new {
220
+ Some ( f) => ViolationFn :: OldFn ( f) ,
221
+ None => ViolationFn :: NoOp
222
+ } ;
223
+ self
224
+ }
225
+
226
+ /// Call the provided function or closure for a non-fatal `SyntaxViolation`
227
+ /// when it occurs during parsing. Note that since the provided function is
228
+ /// `Fn`, the caller might need to utilize _interior mutability_, such as with
229
+ /// a `RefCell`, to collect the violations.
230
+ ///
231
+ /// ## Example
232
+ /// ```
233
+ /// use std::cell::RefCell;
234
+ /// use url::{Url, SyntaxViolation};
235
+ /// # use url::ParseError;
236
+ /// # fn run() -> Result<(), url::ParseError> {
237
+ /// let violations = RefCell::new(Vec::new());
238
+ /// let url = Url::options()
239
+ /// .syntax_violation_callback(Some(&|v| violations.borrow_mut().push(v)))
240
+ /// .parse("https:////example.com")?;
241
+ /// assert_eq!(url.as_str(), "https://example.com/");
242
+ /// assert_eq!(violations.into_inner(),
243
+ /// vec!(SyntaxViolation::ExpectedDoubleSlash));
244
+ /// # Ok(())
245
+ /// # }
246
+ /// # run().unwrap();
247
+ /// ```
248
+ pub fn syntax_violation_callback ( mut self , new : Option < & ' a Fn ( SyntaxViolation ) > ) -> Self {
249
+ self . violation_fn = match new {
250
+ Some ( f) => ViolationFn :: NewFn ( f) ,
251
+ None => ViolationFn :: NoOp
252
+ } ;
215
253
self
216
254
}
217
255
@@ -221,19 +259,20 @@ impl<'a> ParseOptions<'a> {
221
259
serialization : String :: with_capacity ( input. len ( ) ) ,
222
260
base_url : self . base_url ,
223
261
query_encoding_override : self . encoding_override ,
224
- log_syntax_violation : self . log_syntax_violation ,
262
+ violation_fn : self . violation_fn ,
225
263
context : Context :: UrlParser ,
226
264
} . parse_url ( input)
227
265
}
228
266
}
229
267
230
268
impl < ' a > Debug for ParseOptions < ' a > {
231
269
fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
232
- write ! ( f, "ParseOptions {{ base_url: {:?}, encoding_override: {:?}, log_syntax_violation: " , self . base_url, self . encoding_override) ?;
233
- match self . log_syntax_violation {
234
- Some ( _) => write ! ( f, "Some(Fn(&'static str)) }}" ) ,
235
- None => write ! ( f, "None }}" )
236
- }
270
+ write ! ( f,
271
+ "ParseOptions {{ base_url: {:?}, encoding_override: {:?}, \
272
+ violation_fn: {:?} }}",
273
+ self . base_url,
274
+ self . encoding_override,
275
+ self . violation_fn)
237
276
}
238
277
}
239
278
@@ -363,7 +402,7 @@ impl Url {
363
402
ParseOptions {
364
403
base_url : None ,
365
404
encoding_override : EncodingOverride :: utf8 ( ) ,
366
- log_syntax_violation : None ,
405
+ violation_fn : ViolationFn :: NoOp ,
367
406
}
368
407
}
369
408
0 commit comments