Просмотр исходного кода

Make pushing a "." or ".." segment a no-op.

Simon Sapin 10 лет назад
Родитель
Сommit
e66486a7cd
1 измененных файлов с 17 добавлено и 3 удалено
  1. 17 3
      src/path_segments.rs

+ 17 - 3
src/path_segments.rs

@@ -23,8 +23,8 @@ use Url;
 /// assert!(url.path_segments_mut().is_err());
 ///
 /// let mut url = Url::parse("http://example.net/foo/index.html").unwrap();
-/// url.path_segments_mut().unwrap().pop().push("img").push("100%.png");
-/// assert_eq!(url.as_str(), "http://example.net/foo/img/100%25.png");
+/// url.path_segments_mut().unwrap().pop().push("img").push("2/100%.png");
+/// assert_eq!(url.as_str(), "http://example.net/foo/img/2%2F100%25.png");
 /// ```
 pub struct PathSegmentsMut<'a> {
     url: &'a mut Url,
@@ -145,6 +145,16 @@ impl<'a> PathSegmentsMut<'a> {
     /// url.path_segments_mut().unwrap().extend(&[org, repo, "issues", issue_number]);
     /// assert_eq!(url.as_str(), "https://github.com/servo/rust-url/issues/188");
     /// ```
+    ///
+    /// In order to make sure that parsing the serialization of an URL gives the same URL,
+    /// a segment is ignored if it is `"."` or `".."`:
+    ///
+    /// ```rust
+    /// # use url::Url;
+    /// let mut url = Url::parse("https://github.com/servo").unwrap();
+    /// url.path_segments_mut().unwrap().extend(&["..", "rust-url", ".", "pulls"]);
+    /// assert_eq!(url.as_str(), "https://github.com/servo/rust-url/pulls");
+    /// ```
     pub fn extend<I>(&mut self, segments: I) -> &mut Self
     where I: IntoIterator, I::Item: AsRef<str> {
         let scheme_type = SchemeType::from(self.url.scheme());
@@ -152,12 +162,16 @@ impl<'a> PathSegmentsMut<'a> {
         self.url.mutate(|parser| {
             parser.context = parser::Context::PathSegmentSetter;
             for segment in segments {
+                let segment = segment.as_ref();
+                if matches!(segment, "." | "..") {
+                    continue
+                }
                 if parser.serialization.len() > path_start + 1 {
                     parser.serialization.push('/');
                 }
                 let mut has_host = true;  // FIXME account for this?
                 parser.parse_path(scheme_type, &mut has_host, path_start,
-                                  parser::Input::new(segment.as_ref()));
+                                  parser::Input::new(segment));
             }
         });
         self