Skip to content

Commit dd1f232

Browse files
author
Giang N
committed
Squash commit
1 parent 37557e4 commit dd1f232

File tree

1 file changed

+253
-0
lines changed

1 file changed

+253
-0
lines changed

src/lib.rs

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,24 @@ impl Url {
320320
}
321321

322322
/// Return a default `ParseOptions` that can fully configure the URL parser.
323+
///
324+
/// # Examples
325+
///
326+
/// Get default `ParseOptions`, then change base url
327+
///
328+
/// ```rust
329+
/// use url::Url;
330+
/// # use url::ParseError;
331+
/// # fn run() -> Result<(), ParseError> {
332+
/// let options = Url::options();
333+
/// let api = Url::parse("https://api.example.com")?;
334+
/// let base_url = options.base_url(Some(&api));
335+
/// let version_url = base_url.parse("version.json")?;
336+
/// assert_eq!(version_url.as_str(), "https://api.example.com/version.json");
337+
/// # Ok(())
338+
/// # }
339+
/// # run().unwrap();
340+
/// ```
323341
pub fn options<'a>() -> ParseOptions<'a> {
324342
ParseOptions {
325343
base_url: None,
@@ -936,6 +954,25 @@ impl Url {
936954
/// For cannot-be-a-base URLs, this is an arbitrary string that doesn’t start with '/'.
937955
/// For other URLs, this starts with a '/' slash
938956
/// and continues with slash-separated path segments.
957+
///
958+
/// # Examples
959+
///
960+
/// ```rust
961+
/// use url::{Url, ParseError};
962+
///
963+
/// # fn run() -> Result<(), ParseError> {
964+
/// let url = Url::parse("https://example.com/api/versions?page=2")?;
965+
/// assert_eq!(url.path(), "/api/versions");
966+
///
967+
/// let url = Url::parse("https://example.com")?;
968+
/// assert_eq!(url.path(), "/");
969+
///
970+
/// let url = Url::parse("https://example.com/countries/việt nam")?;
971+
/// assert_eq!(url.path(), "/countries/vi%E1%BB%87t%20nam");
972+
/// # Ok(())
973+
/// # }
974+
/// # run().unwrap();
975+
/// ```
939976
pub fn path(&self) -> &str {
940977
match (self.query_start, self.fragment_start) {
941978
(None, None) => self.slice(self.path_start..),
@@ -975,6 +1012,11 @@ impl Url {
9751012
///
9761013
/// let url = Url::parse("data:text/plain,HelloWorld")?;
9771014
/// assert!(url.path_segments().is_none());
1015+
///
1016+
/// let url = Url::parse("https://example.com/countries/việt nam")?;
1017+
/// let mut path_segments = url.path_segments().ok_or_else(|| "cannot be base")?;
1018+
/// assert_eq!(path_segments.next(), Some("countries"));
1019+
/// assert_eq!(path_segments.next(), Some("vi%E1%BB%87t%20nam"));
9781020
/// # Ok(())
9791021
/// # }
9801022
/// # run().unwrap();
@@ -989,6 +1031,29 @@ impl Url {
9891031
}
9901032

9911033
/// Return this URL’s query string, if any, as a percent-encoded ASCII string.
1034+
///
1035+
/// # Examples
1036+
///
1037+
/// ```rust
1038+
/// use url::Url;
1039+
/// # use url::ParseError;
1040+
///
1041+
/// fn run() -> Result<(), ParseError> {
1042+
/// let url = Url::parse("https://example.com/products?page=2")?;
1043+
/// let query = url.query();
1044+
/// assert_eq!(query, Some("page=2"));
1045+
///
1046+
/// let url = Url::parse("https://example.com/products")?;
1047+
/// let query = url.query();
1048+
/// assert!(query.is_none());
1049+
///
1050+
/// let url = Url::parse("https://example.com/?country=español")?;
1051+
/// let query = url.query();
1052+
/// assert_eq!(query, Some("country=espa%C3%B1ol"));
1053+
/// # Ok(())
1054+
/// # }
1055+
/// # run().unwrap();
1056+
/// ```
9921057
pub fn query(&self) -> Option<&str> {
9931058
match (self.query_start, self.fragment_start) {
9941059
(None, _) => None,
@@ -1005,6 +1070,28 @@ impl Url {
10051070

10061071
/// Parse the URL’s query string, if any, as `application/x-www-form-urlencoded`
10071072
/// and return an iterator of (key, value) pairs.
1073+
///
1074+
/// # Examples
1075+
///
1076+
/// ```rust
1077+
/// use std::borrow::Cow;
1078+
///
1079+
/// use url::Url;
1080+
/// # use url::ParseError;
1081+
///
1082+
/// # fn run() -> Result<(), ParseError> {
1083+
/// let url = Url::parse("https://example.com/products?page=2&sort=desc")?;
1084+
/// let mut pairs = url.query_pairs();
1085+
///
1086+
/// assert_eq!(pairs.count(), 2);
1087+
///
1088+
/// assert_eq!(pairs.next(), Some((Cow::Borrowed("page"), Cow::Borrowed("2"))));
1089+
/// assert_eq!(pairs.next(), Some((Cow::Borrowed("sort"), Cow::Borrowed("desc"))));
1090+
/// # Ok(())
1091+
/// # }
1092+
/// # run().unwrap();
1093+
///
1094+
10081095
#[inline]
10091096
pub fn query_pairs(&self) -> form_urlencoded::Parse {
10101097
form_urlencoded::parse(self.query().unwrap_or("").as_bytes())
@@ -1023,6 +1110,25 @@ impl Url {
10231110
///
10241111
/// **Note:** the parser did *not* percent-encode this component,
10251112
/// but the input may have been percent-encoded already.
1113+
///
1114+
/// # Examples
1115+
///
1116+
/// ```rust
1117+
/// use url::Url;
1118+
/// # use url::ParseError;
1119+
///
1120+
/// # fn run() -> Result<(), ParseError> {
1121+
/// let url = Url::parse("https://example.com/data.csv#row=4")?;
1122+
///
1123+
/// assert_eq!(url.fragment(), Some("row=4"));
1124+
///
1125+
/// let url = Url::parse("https://example.com/data.csv#cell=4,1-6,2")?;
1126+
///
1127+
/// assert_eq!(url.fragment(), Some("cell=4,1-6,2"));
1128+
/// # Ok(())
1129+
/// # }
1130+
/// # run().unwrap();
1131+
/// ```
10261132
pub fn fragment(&self) -> Option<&str> {
10271133
self.fragment_start.map(|start| {
10281134
debug_assert!(self.byte_at(start) == b'#');
@@ -1038,6 +1144,28 @@ impl Url {
10381144
}
10391145

10401146
/// Change this URL’s fragment identifier.
1147+
///
1148+
/// # Examples
1149+
///
1150+
/// ```rust
1151+
/// use url::Url;
1152+
/// # use url::ParseError;
1153+
///
1154+
/// # fn run() -> Result<(), ParseError> {
1155+
/// let mut url = Url::parse("https://example.com/data.csv")?;
1156+
/// assert_eq!(url.as_str(), "https://example.com/data.csv");
1157+
1158+
/// url.set_fragment(Some("cell=4,1-6,2"));
1159+
/// assert_eq!(url.as_str(), "https://example.com/data.csv#cell=4,1-6,2");
1160+
/// assert_eq!(url.fragment(), Some("cell=4,1-6,2"));
1161+
///
1162+
/// url.set_fragment(None);
1163+
/// assert_eq!(url.as_str(), "https://example.com/data.csv");
1164+
/// assert!(url.fragment().is_none());
1165+
/// # Ok(())
1166+
/// # }
1167+
/// # run().unwrap();
1168+
/// ```
10411169
pub fn set_fragment(&mut self, fragment: Option<&str>) {
10421170
// Remove any previous fragment
10431171
if let Some(start) = self.fragment_start {
@@ -1073,6 +1201,24 @@ impl Url {
10731201
}
10741202

10751203
/// Change this URL’s query string.
1204+
///
1205+
/// # Examples
1206+
///
1207+
/// ```rust
1208+
/// use url::Url;
1209+
/// # use url::ParseError;
1210+
///
1211+
/// # fn run() -> Result<(), ParseError> {
1212+
/// let mut url = Url::parse("https://example.com/products")?;
1213+
/// assert_eq!(url.as_str(), "https://example.com/products");
1214+
///
1215+
/// url.set_query(Some("page=2"));
1216+
/// assert_eq!(url.as_str(), "https://example.com/products?page=2");
1217+
/// assert_eq!(url.query(), Some("page=2"));
1218+
/// # Ok(())
1219+
/// # }
1220+
/// # run().unwrap();
1221+
/// ```
10761222
pub fn set_query(&mut self, query: Option<&str>) {
10771223
let fragment = self.take_fragment();
10781224

@@ -1153,6 +1299,27 @@ impl Url {
11531299
}
11541300

11551301
/// Change this URL’s path.
1302+
///
1303+
/// # Examples
1304+
///
1305+
/// ```rust
1306+
/// use url::Url;
1307+
/// # use url::ParseError;
1308+
///
1309+
/// # fn run() -> Result<(), ParseError> {
1310+
/// let mut url = Url::parse("https://example.com")?;
1311+
/// url.set_path("api/comments");
1312+
/// assert_eq!(url.as_str(), "https://example.com/api/comments");
1313+
/// assert_eq!(url.path(), "/api/comments");
1314+
///
1315+
/// let mut url = Url::parse("https://example.com/api")?;
1316+
/// url.set_path("data/report.csv");
1317+
/// assert_eq!(url.as_str(), "https://example.com/data/report.csv");
1318+
/// assert_eq!(url.path(), "/data/report.csv");
1319+
/// # Ok(())
1320+
/// # }
1321+
/// # run().unwrap();
1322+
/// ```
11561323
pub fn set_path(&mut self, mut path: &str) {
11571324
let after_path = self.take_after_path();
11581325
let old_after_path_pos = to_u32(self.serialization.len()).unwrap();
@@ -1427,6 +1594,38 @@ impl Url {
14271594
/// If this URL is cannot-be-a-base, do nothing and return `Err`.
14281595
///
14291596
/// Compared to `Url::set_host`, this skips the host parser.
1597+
///
1598+
/// # Examples
1599+
///
1600+
/// ```rust
1601+
/// use url::{Url, ParseError};
1602+
///
1603+
/// # fn run() -> Result<(), ParseError> {
1604+
/// let mut url = Url::parse("http://example.com")?;
1605+
/// url.set_ip_host("127.0.0.1".parse().unwrap());
1606+
/// assert_eq!(url.host_str(), Some("127.0.0.1"));
1607+
/// assert_eq!(url.as_str(), "http://127.0.0.1/");
1608+
/// # Ok(())
1609+
/// # }
1610+
/// # run().unwrap();
1611+
/// ```
1612+
///
1613+
/// Cannot change URL's from mailto(cannot-be-base) to ip:
1614+
///
1615+
/// ```rust
1616+
/// use url::{Url, ParseError};
1617+
///
1618+
/// # fn run() -> Result<(), ParseError> {
1619+
/// let mut url = Url::parse("mailto:[email protected]")?;
1620+
/// let result = url.set_ip_host("127.0.0.1".parse().unwrap());
1621+
///
1622+
/// assert_eq!(url.as_str(), "mailto:[email protected]");
1623+
/// assert!(result.is_err());
1624+
/// # Ok(())
1625+
/// # }
1626+
/// # run().unwrap();
1627+
/// ```
1628+
///
14301629
pub fn set_ip_host(&mut self, address: IpAddr) -> Result<(), ()> {
14311630
if self.cannot_be_a_base() {
14321631
return Err(())
@@ -1443,6 +1642,29 @@ impl Url {
14431642
/// Change this URL’s password.
14441643
///
14451644
/// If this URL is cannot-be-a-base or does not have a host, do nothing and return `Err`.
1645+
///
1646+
/// # Examples
1647+
///
1648+
/// ```rust
1649+
/// use url::{Url, ParseError};
1650+
///
1651+
/// # fn run() -> Result<(), ParseError> {
1652+
/// let mut url = Url::parse("mailto:[email protected]")?;
1653+
/// let result = url.set_password(Some("secret_password"));
1654+
/// assert!(result.is_err());
1655+
///
1656+
/// let mut url = Url::parse("ftp://user1:[email protected]")?;
1657+
/// let result = url.set_password(Some("secret_password"));
1658+
/// assert_eq!(url.password(), Some("secret_password"));
1659+
///
1660+
/// let mut url = Url::parse("ftp://user2:@example.com")?;
1661+
/// let result = url.set_password(Some("secret2"));
1662+
/// assert!(result.is_ok());
1663+
/// assert_eq!(url.password(), Some("secret2"));
1664+
/// # Ok(())
1665+
/// # }
1666+
/// # run().unwrap();
1667+
/// ```
14461668
pub fn set_password(&mut self, password: Option<&str>) -> Result<(), ()> {
14471669
if !self.has_host() {
14481670
return Err(())
@@ -1492,6 +1714,37 @@ impl Url {
14921714
/// Change this URL’s username.
14931715
///
14941716
/// If this URL is cannot-be-a-base or does not have a host, do nothing and return `Err`.
1717+
/// # Examples
1718+
///
1719+
/// Cannot setup username from mailto(cannot-be-base)
1720+
///
1721+
/// ```rust
1722+
/// use url::{Url, ParseError};
1723+
///
1724+
/// # fn run() -> Result<(), ParseError> {
1725+
/// let mut url = Url::parse("mailto:[email protected]")?;
1726+
/// let result = url.set_username("user1");
1727+
/// assert_eq!(url.as_str(), "mailto:[email protected]");
1728+
/// assert!(result.is_err());
1729+
/// # Ok(())
1730+
/// # }
1731+
/// # run().unwrap();
1732+
/// ```
1733+
///
1734+
/// Setup username to user1
1735+
/// ```rust
1736+
/// use url::{Url, ParseError};
1737+
///
1738+
/// # fn run() -> Result<(), ParseError> {
1739+
/// let mut url = Url::parse("ftp://:[email protected]")?;
1740+
/// let result = url.set_username("user1");
1741+
/// assert!(result.is_ok());
1742+
/// assert_eq!(url.username(), "user1");
1743+
/// assert_eq!(url.as_str(), "ftp://user1:[email protected]");
1744+
/// # Ok(())
1745+
/// # }
1746+
/// # run().unwrap();
1747+
/// ```
14951748
pub fn set_username(&mut self, username: &str) -> Result<(), ()> {
14961749
if !self.has_host() {
14971750
return Err(())

0 commit comments

Comments
 (0)