From 578038619f192a9e7308c1355e6d35c033e76413 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Fri, 29 May 2020 17:44:28 -0700 Subject: [PATCH] Add 'Origin::map_path()' method. --- core/http/src/uri/origin.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/core/http/src/uri/origin.rs b/core/http/src/uri/origin.rs index 00479a40..45962e9b 100644 --- a/core/http/src/uri/origin.rs +++ b/core/http/src/uri/origin.rs @@ -316,6 +316,42 @@ impl<'a> Origin<'a> { self.path.from_cow_source(&self.source) } + /// Applies the function `f` to the internal `path` and returns a new + /// `Origin` with the new path. If the path returned from `f` is invalid, + /// returns `None`. Otherwise, returns `Some`, even if the new path is + /// _abnormal_. + /// + /// ### Examples + /// + /// Affix a trailing slash if one isn't present. + /// + /// ```rust + /// # extern crate rocket; + /// use rocket::http::uri::Origin; + /// + /// let old_uri = Origin::parse("/a/b/c").unwrap(); + /// let expected_uri = Origin::parse("/a/b/c/").unwrap(); + /// assert_eq!(old_uri.map_path(|p| p.to_owned() + "/"), Some(expected_uri)); + /// + /// let old_uri = Origin::parse("/a/b/c/").unwrap(); + /// let expected_uri = Origin::parse("/a/b/c//").unwrap(); + /// assert_eq!(old_uri.map_path(|p| p.to_owned() + "/"), Some(expected_uri)); + /// ``` + #[inline] + pub fn map_path String>(&self, f: F) -> Option { + let path = f(self.path()); + if !path.starts_with('/') || !path.bytes().all(crate::parse::uri::is_pchar) { + return None; + } + + Some(Origin { + source: self.source.clone(), + path: path.into(), + query: self.query.clone(), + segment_count: Storage::new(), + }) + } + /// Returns the query part of this URI without the question mark, if there is /// any. ///