tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.pwd && rg -n "BeforePath|AfterPort|non-special|cannot-be-a-base|path_start|serialization|serialize|join|relative|Position" url/src -S
Chunk ID: ec4e39
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 10052
Output:
Total output lines: 516
/app
url/src/host.rs:15:use serde::{Deserialize, Serialize};
url/src/host.rs:19:#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
url/src/host.rs:40:#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
url/src/host.rs:45: /// a special URL, or percent encoded for non-special URLs. Hosts for
url/src/host.rs:46: /// non-special URLs are also called opaque hosts.
url/src/host.rs:50: /// `Url::host_str` returns the serialization of this address,
url/src/host.rs:55: /// `Url::host_str` returns the serialization of that address between `[` and `]` brackets,
url/src/host.rs:223:// https://url.spec.whatwg.org/#concept-ipv6-serializer step 2 and 3
url/src/host.rs:250: // https://url.spec.whatwg.org/#concept-ipv6-serializer
url/src/slicing.rs:15: &self.serialization
url/src/slicing.rs:19:impl Index<RangeFrom<Position>> for Url {
url/src/slicing.rs:21: fn index(&self, range: RangeFrom<Position>) -> &str {
url/src/slicing.rs:22: &self.serialization[self.index(range.start)..]
url/src/slicing.rs:26:impl Index<RangeTo<Position>> for Url {
url/src/slicing.rs:28: fn index(&self, range: RangeTo<Position>) -> &str {
url/src/slicing.rs:29: &self.serialization[..self.index(range.end)]
url/src/slicing.rs:33:impl Index<Range<Position>> for Url {
url/src/slicing.rs:35: fn index(&self, range: Range<Position>) -> &str {
url/src/slicing.rs:36: &self.serialization[self.index(range.start)..self.index(range.end)]
url/src/slicing.rs:45:/// # use url::{Url, Position};
url/src/slicing.rs:47:/// let serialization: &str = &some_url[..];
url/src/slicing.rs:48:/// let serialization_without_fragment: &str = &some_url[..Position::AfterQuery];
url/src/slicing.rs:49:/// let authority: &str = &some_url[Position::BeforeUsername..Position::AfterPort];
url/src/slicing.rs:50:/// let data_url_payload: &str = &some_url[Position::BeforePath..Position::AfterQuery];
url/src/slicing.rs:51:/// let scheme_relative: &str = &some_url[Position::BeforeUsername..];
url/src/slicing.rs:81:pub enum Position {
url/src/slicing.rs:91: AfterPort,
url/src/slicing.rs:92: BeforePath,
url/src/slicing.rs:102: fn index(&self, position: Position) -> usize {
url/src/slicing.rs:104: Position::BeforeScheme => 0,
url/src/slicing.rs:106: Position::AfterScheme => self.scheme_end as usize,
url/src/slicing.rs:108: Position::BeforeUsername => {
url/src/slicing.rs:118: Position::AfterUsername => self.username_end as usize,
url/src/slicing.rs:120: Position::BeforePassword => {
url/src/slicing.rs:129: Position::AfterPassword => {
url/src/slicing.rs:139: Position::BeforeHost => self.host_start as usize,
url/src/slicing.rs:141: Position::AfterHost => self.host_end as usize,
url/src/slicing.rs:143: Position::BeforePort => {
url/src/slicing.rs:152: Position::AfterPort => self.path_start as usize,
url/src/slicing.rs:154: Position::BeforePath => self.path_start as usize,
url/src/slicing.rs:156: Position::AfterPath => match (self.query_start, self.fragment_start) {
url/src/slicing.rs:159: (None, None) => self.serialization.len(),
url/src/slicing.rs:162: Position::BeforeQuery => match (self.query_start, self.fragment_start) {
url/src/slicing.rs:168: (None, None) => self.serialization.len(),
url/src/slicing.rs:171: Position::AfterQuery => match self.fragment_start {
url/src/slicing.rs:172: None => self.serialization.len(),
url/src/slicing.rs:176: Position::BeforeFragment => match self.fragment_start {
url/src/slicing.rs:181: None => self.serialization.len(),
url/src/slicing.rs:184: Position::AfterFragment => self.serialization.len(),
url/src/origin.rs:75: pub fn ascii_serialization(&self) -> String {
url/src/origin.rs:89: pub fn unicode_serialization(&self) -> String {
url/src/quirks.rs:15:use crate::{Host, ParseError, Position, Url};
url/src/quirks.rs:23:/// | | | | | `----------------- path_start
url/src/quirks.rs:37: pub path_start: u32,
url/src/quirks.rs:44:/// This can be useful for implementing efficient serialization
url/src/quirks.rs:54: path_start: url.path_start,
url/src/quirks.rs:92: url.origin().ascii_serialization()
url/src/quirks.rs:143: &url[Position::BeforeHost..Position::AfterPort]
url/src/quirks.rs:149: // If context object’s url’s cannot-be-a-base-URL flag is set, then return.
url/src/quirks.rs:238: &url[Position::BeforePort..Position::AfterPort]
url/src/quirks.rs:291: trim(&url[Position::AfterPath..Position::AfterQuery])
url/src/quirks.rs:305: trim(&url[Position::AfterQuery..])
url/src/lib.rs:28:use url::{Url, Host, Position};
url/src/lib.rs:46:assert!(&issue_list_url[Position::BeforePath..] == "/rust-lang/rust/issues?labels=E-easy&state=open");
url/src/lib.rs:54:Some URLs are said to be *cannot-be-a-base*:
url/src/lib.rs:78:Enable the `serde` feature to include `Deserialize` and `Serialize` implementations for `url::Url`.
url/src/lib.rs:82:Many contexts allow URL *references* that can be relative to a *base URL*:
url/src/lib.rs:88:Since parsed URLs are absolute, giving a base is required for parsing relative URLs:
url/src/lib.rs:96:Use the `join` method on an `Url` to use it as a base URL:
url/src/lib.rs:104:let css_url = this_document.join("../main.css")?;
url/src/lib.rs:115:[`serde::Deserialize`](https://docs.rs/serde/1/serde/trait.Deserialize.html).
url/src/lib.rs:156:pub use crate::slicing::Position;
url/src/lib.rs:180: serialization: String,
url/src/lib.rs:189: path_start: u32, // Before initial '/', if any
url/src/lib.rs:190: query_start: Option<u32>, // Before '?', unlike Position::QueryStart
url/src/lib.rs:191: fragment_start: Option<u32>, // Before '#', unlike Position::FragmentStart
url/src/lib.rs:246: serialization: String::with_capacity(input.len()),
url/src/lib.rs:340: .serialization
url/src/lib.rs:346: let start = self.serialization.len() - trailing_space_count;
url/src/lib.rs:348: self.serialization.truncate(start);
url/src/lib.rs:353: /// The inverse of this is [`make_relative`].
url/src/lib.rs:367: /// let url = base.join("c.png")?;
url/src/lib.rs:371: /// let url = base.join("c.png")?;
url/src/lib.rs:384: /// [`make_relative`]: #method.make_relative
url/src/lib.rs:386: pub fn join(&self, input: &str) -> Result<Url, crate::ParseError> {
url/src/lib.rs:390: /// Creates a relative URL if possible, with this URL as the base URL.
url/src/lib.rs:392: /// This is the inverse of [`join`].
url/src/lib.rs:403: /// let relative = base.make_relative(&url);
url/src/lib.rs:404: /// assert_eq!(relative.as_ref().map(|s| s.as_str()), Some("c.png"));
url/src/lib.rs:408: /// let relative = base.make_relative(&url);
url/src/lib.rs:409: /// assert_eq!(relative.as_ref().map(|s| s.as_str()), Some("c.png"));
url/src/lib.rs:413: /// let relative = base.make_relative(&url);
url/src/lib.rs:414: /// assert_eq!(relative.as_ref().map(|s| s.as_str()), Some("../d/c.png"));
url/src/lib.rs:418: /// let relative = base.make_relative(&url);
url/src/lib.rs:419: /// assert_eq!(relative.as_ref().map(|s| s.as_str()), Some("?e=f"));
url/src/lib.rs:430: /// [`join`]: #method.join
url/src/lib.rs:431: pub fn make_relative(&self, url: &Url) -> Option<String> {
url/src/lib.rs:444: let mut relative = String::new();
url/src/lib.rs:476: if !relative.is_empty() {
url/src/lib.rs:477: relative.push('/');
url/src/lib.rs:480: relative.push_str("..");
url/src/lib.rs:485: if !relative.is_empty() {
url/src/lib.rs:486: relative.push('/');
url/src/lib.rs:489: relative.push_str(url_path_segment);
url/src/lib.rs:493: if !relative.is_empty() || base_filename != url_filename {
url/src/lib.rs:499: relative.push('/');
url/src/lib.rs:501: if !relative.is_empty() {
url/src/lib.rs:502: relative.push('/');
url/src/lib.rs:504: relative.push_str(url_filename);
url/src/lib.rs:510: relative.push('?');
url/src/lib.rs:511: relative.push_str(query);
url/src/lib.rs:515: relative.push('#');
url/src/lib.rs:516: relative.push_str(fragment);
url/src/lib.rs:519: Some(relative)
url/src/lib.rs:549: /// Return the serialization of this URL.
url/src/lib.rs:551: /// This is fast since that serialization is already stored in the `Url` struct.
url/src/lib.rs:569: &self.serialization
url/src/lib.rs:572: /// Return the serialization of this URL.
url/src/lib.rs:609: self.serialization
url/src/lib.rs:623: self.serialization))
url/src/lib.rs:639: if self.username_end != self.serialization.len() as u32 {
url/src/lib.rs:665: if self.path_start == self.host_end {
url/src/lib.rs:669: let port_str = self.slice(self.host_end + 1..self.path_start);
url/src/lib.rs:676: self.path_start as usize == self.serialization.len()
url/src/lib.rs:677: || matches!(self.byte_at(self.path_start), b'/' | b'#' | b'?')
url/src/lib.rs:686: assert_eq!(self.path_start, self.scheme_end + 1);
url/src/lib.rs:689: assert!(start >= self.path_start);
url/src/lib.rs:693: assert!(start >= self.path_start);
url/src/lib.rs:701: assert_eq!(&self.serialization, &other.serialization);
url/src/lib.rs:713: assert_eq!(self.path_start, other.path_start);
url/src/lib.rs:819: /// or cannot-be-a-base like `data:text/plain,Stuff`.
url/src/lib.rs:851: /// of a special URL, or percent encoded for non-special URLs.
url/src/lib.rs:882: if self.has_authority() && self.path_start > self.scheme_end + scheme_separator_len {
url/src/lib.rs:883: self.slice(self.scheme_end + scheme_separator_len..self.path_start)
url/src/lib.rs:889: /// Return whether this URL is a cannot-be-a-base URL,
url/src/lib.rs:890: /// meaning that parsing a relative URL string with this URL as the base will return an error.
url/src/lib.rs:978: && self.username_end != self.serialization.len() as u32
url/src/lib.rs:1016: /// of a special URL, or percent encoded for non-special URLs.
url/src/lib.rs:1056: /// of a special URL, or percent encoded for non-special URLs.
url/src/lib.rs:1096: /// of a special URL, or percent encoded for non-special URLs.
url/src/lib.rs:1126: /// Note that default port numbers are never reflected by the serialization,
url/src/lib.rs:1241: /// For cannot-be-a-base URLs, this is an arbitrary string that doesn’t start with '/'.
url/src/lib.rs:1265: (None, None) => self.slice(self.path_start..),
url/src/lib.rs:1267: self.slice(self.path_start..next_component_start)
url/src/lib.rs:1272: /// Unless this URL is cannot-be-a-base,
url/src/lib.rs:1276: /// Return `None` for cannot-be-a-base URLs.
url/src/lib.rs:1422: let mut parser = Parser::for_setter(mem::take(&mut self.serialization));
url/src/lib.rs:1424: self.serialization = parser.serialization;
url/src/lib.rs:1455: self.serialization.truncate(start as usize);
url/src/lib.rs:1459: self.fragment_start = Some(to_u32(self.serialization.len()).unwrap());
url/src/lib.rs:1460: self.serialization.push('#');
url/src/lib.rs:1472: self.serialization.truncate(start as usize);
url/src/lib.rs:1480: self.fragment_start = Some(to_u32(self.serialization.len()).unwrap());
url/src/lib.rs:1481: self.serialization.push('#');
url/src/lib.rs:1482: self.serialization.push_str(fragment);
url/src/lib.rs:1511: self.serialization.truncate(start as usize);
url/src/lib.rs:1515: self.query_start = Some(to_u32(self.serialization.len()).unwrap());
url/src/lib.rs:1516: self.serialization.push('?');
url/src/lib.rs:1575: query_start = self.serialization.len();
url/src/lib.rs:1577: self.serialization.push('?');
url/src/lib.rs:1591: self.serialization.truncate(i as usize);
url/src/lib.rs:1635: let old_after_path_pos = to_u32(self.serialization.len()).unwrap();
url/src/lib.rs:1638: self.serialization.truncate(self.path_start as usize);
url/src/lib.rs:1642: parser.serialization.push_str("%2F");
url/src/lib.rs:1648: parser.parse_path_start(scheme_type, &mut has_host, parser::Input::new(path));
url/src/lib.rs:1656: /// Return `Err(())` if this URL is cannot-be-a-base.
url/src/lib.rs:1667: let new_after_path_position = to_u32(self.serialization.len()).unwrap();
url/src/lib.rs:1678: self.serialization.push_str(after_path)
url/src/lib.rs:1683: /// Note that default port numbers are not reflected in the serialization.
url/src/lib.rs:1685: /// If this URL is cannot-be-a-base, does not have a host, or has the `file` scheme;
url/src/lib.rs:1723: /// Cannot set port for cannot-be-a-base URLs:
url/src/lib.rs:1758: self.serialization
url/src/lib.rs:1759: .drain(self.host_end as usize..self.path_start as usize);
url/src/lib.rs:1760: let offset = self.path_start - self.host_end;
url/src/lib.rs:1761: self.path_start = self.host_end;
url/src/lib.rs:1771: let path_and_after = self.slice(self.path_start..).to_owned();
url/src/lib.rs:1772: self.serialization.truncate(self.host_end as usize);
url/src/lib.rs:1773: write!(&mut self.serialization, ":{}", new).unwrap();
url/src/lib.rs:1774: let old_path_start = self.path_start;
url/src/lib.rs:1775: let new_path_start = to_u32(self.serialization.len()).unwrap();
url/src/lib.rs:1776: self.path_start = new_path_start;
url/src/lib.rs:1778: *index -= old_path_start;
url/src/lib.rs:1779: *index += new_path_start;
url/src/lib.rs:1787: self.serialization.push_str(&path_and_after);
url/src/lib.rs:1848: /// Cannot change or remove host for cannot-be-a-base URLs:
url/src/lib.rs:1871: /// If this URL is cannot-be-a-base or there is an error parsing the given `host`,
url/src/lib.rs:1909: } else if self.serialization.len() == self.path_start as usize {
url/src/lib.rs:1910: self.serialization.push('/');
url/src/lib.rs:1913: debug_assert!(self.byte_at(self.path_start) == b'/');
url/src/lib.rs:1915: let new_path_start = if scheme_type.is_file() {
url/src/lib.rs:1921: self.serialization
url/src/lib.rs:1922: .drain(new_path_start as usize..self.path_start as usize);
url/src/lib.rs:1923: let offset = self.path_start - new_path_start;
url/src/lib.rs:1924: self.path_start = new_path_start;
url/src/lib.rs:1925: self.username_end = new_path_start;
url/src/lib.rs:1926: self.host_start = new_path_start;
url/src/lib.rs:1927: self.host_end = new_path_start;
url/src/lib.rs:1942: self.path_start
url/src/lib.rs:1947: self.serialization.truncate(self.host_start as usize);
url/src/lib.rs:1951: self.serialization.push('/');
url/src/lib.rs:1952: self.serialization.push('/');
url/src/lib.rs:1956: write!(&mut self.serialization, "{}", host).unwrap();
url/src/lib.rs:1957: self.host_end = to_u32(self.serialization.len()).unwrap();
url/src/lib.rs:1963: write!(&mut self.serialization, ":{}", port).unwrap();
url/src/lib.rs:1966: let new_suffix_pos = to_u32(self.serialization.len()).unwrap();
url/src/lib.rs:1967: self.serialization.push_str(&suffix);
url/src/lib.rs:1973: adjust(&mut self.path_start);
url/src/lib.rs:1984: /// If this URL is cannot-be-a-base, do nothing and return `Err`.
url/src/lib.rs:2035: /// If this URL is cannot-be-a-base or does not have a host, do nothing and return `Err`.
url/src/lib.rs:2067: self.serialization.truncate(self.username_end as usize);
url/src/lib.rs:2068: self.serialization.push(':');
url/src/lib.rs:2069: self.serialization
url/src/lib.rs:2071: self.serialization.push('@');
url/src/lib.rs:2074: let new_host_start = to_u32(self.serialization.len()).unwrap();
url/src/lib.rs:2081: adjust(&mut self.path_start);
url/src/lib.rs:2089: self.serialization.push_str(&host_and_after);
url/src/lib.rs:2102: self.serialization.drain(start as usize..end as usize);
url/src/lib.rs:2106: self.path_start -= offset;
url/src/lib.rs:2119: /// If this URL is cannot-be-a-base or does not have a host, do nothing and return `Err`.
url/src/lib.rs:2164: self.serialization.truncate(username_start as usize);
url/src/lib.rs:2165: self.serialization
url/src/lib.rs:2169: self.username_end = to_u32(self.serialization.len()).unwrap();
url/src/lib.rs:2176: self.serialization.push_str(&after_username[1..]);
url/src/lib.rs:2179: self.serialization.push_str(&after_username);
url/src/lib.rs:2183: self.serialization.push('@');
url/src/lib.rs:2184: self.serialization.push_str(&after_username);
url/src/lib.rs:2194: adjust(&mut self.path_start);
url/src/lib.rs:2209: /// * If this URL is cannot-be-a-base and the new scheme is one of
url/src/lib.rs:2269: /// Cannot change URL’s scheme from `mailto` (cannot-be-a-base) to `https`:
url/src/lib.rs:2318: let new_scheme_type = SchemeType::from(&parser.serialization);
url/src/lib.rs:2335: let new_scheme_end = to_u32(parser.serialization.len()).unwrap();
url/src/lib.rs:2345: adjust(&mut self.path_start);
url/src/lib.rs:2353: parser.serialization.push_str(self.slice(old_scheme_end..));
url/src/lib.rs:2354: self.serialization = parser.serialization;
url/src/lib.rs:2396: let mut serialization = "file://".to_owned();
url/src/lib.rs:2397: let host_start = serialization.len() as u32;
url/src/lib.rs:2398: let (host_end, host) = path_to_file_url_segments(path.as_ref(), &mut serialization)?;
url/src/lib.rs:2400: serialization,
url/src/lib.rs:2407: path_start: host_end,
url/src/lib.rs:2434: if !url.serialization.ends_with('/') {
url/src/lib.rs:2435: url.serialization.push('/')
url/src/lib.rs:2442: /// The corresponding `deserialize_internal` method sacrifices some invariant-checking
url/src/lib.rs:2443: /// for speed, compared to the `Deserialize` trait impl.
url/src/lib.rs:2448: pub fn serialize_internal<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
url/src/lib.rs:2456: ref serialization,
url/src/lib.rs:2463: ref path_start,
url/src/lib.rs:2468: serialization,
url/src/lib.rs:2475: path_start,
url/src/lib.rs:2479: .serialize(serializer)
url/src/lib.rs:2484: /// The corresponding `deserialize_internal` method sacrifices some invariant-checking
url/src/lib.rs:2485: /// for speed, compared to the `Deserialize` trait impl.
url/src/lib.rs:2490: pub fn deserialize_internal<'de, D>(deserializer: D) -> Result<Self, D::Error>
url/src/lib.rs:2492: D: serde::Deserializer<'de>,
url/src/lib.rs:2494: use serde::de::{Deserialize, Error, Unexpected};
url/src/lib.rs:2496: serialization,
url/src/lib.rs:2503: path_start,
url/src/lib.rs:2506: ) = Deserialize::deserialize(deserializer)?;
url/src/lib.rs:2508: serialization,
url/src/lib.rs:2515: path_start,
url/src/lib.rs:2554: Some(&self.serialization[self.host_start as usize..self.host_end as usize…52 tokens truncated…c/lib.rs:2602: fmt::Display::fmt(&self.serialization, formatter)
url/src/lib.rs:2609: value.serialization
url/src/lib.rs:2613:/// Debug the serialization of this URL.
url/src/lib.rs:2632:/// URLs compare like their serialization.
url/src/lib.rs:2635:/// URLs compare like their serialization.
url/src/lib.rs:2639: self.serialization == other.serialization
url/src/lib.rs:2643:/// URLs compare like their serialization.
url/src/lib.rs:2647: self.serialization.cmp(&other.serialization)
url/src/lib.rs:2651:/// URLs compare like their serialization.
url/src/lib.rs:2655: self.serialization.partial_cmp(&other.serialization)
url/src/lib.rs:2659:/// URLs hash like their serialization.
url/src/lib.rs:2666: hash::Hash::hash(&self.serialization, state)
url/src/lib.rs:2670:/// Return the serialization of this URL.
url/src/lib.rs:2674: &self.serialization
url/src/lib.rs:2708: fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
url/src/lib.rs:2712: serializer.serialize_str(self.as_str())
url/src/lib.rs:2716:/// Deserializes this URL from a `serde` stream.
url/src/lib.rs:2720:impl<'de> serde::Deserialize<'de> for Url {
url/src/lib.rs:2721: fn deserialize<D>(deserializer: D) -> Result<Url, D::Error>
url/src/lib.rs:2723: D: serde::Deserializer<'de>,
url/src/lib.rs:2747: deserializer.deserialize_str(UrlVisitor)
url/src/lib.rs:2754: serialization: &mut String,
url/src/lib.rs:2763: let host_end = to_u32(serialization.len()).unwrap();
url/src/lib.rs:2768: serialization.push('/');
url/src/lib.rs:2769: serialization.extend(percent_encode(
url/src/lib.rs:2776: serialization.push('/');
url/src/lib.rs:2784: serialization: &mut String,
url/src/lib.rs:2786: path_to_file_url_segments_windows(path, serialization)
url/src/lib.rs:2793: serialization: &mut String,
url/src/lib.rs:2801: let host_start = serialization.len() + 1;
url/src/lib.rs:2808: host_end = to_u32(serialization.len()).unwrap();
url/src/lib.rs:2810: serialization.push('/');
url/src/lib.rs:2811: serialization.push(letter as char);
url/src/lib.rs:2812: serialization.push(':');
url/src/lib.rs:2816: write!(serialization, "{}", host).unwrap();
url/src/lib.rs:2817: host_end = to_u32(serialization.len()).unwrap();
url/src/lib.rs:2819: serialization.push('/');
url/src/lib.rs:2821: serialization.extend(percent_encode(share.as_bytes(), PATH_SEGMENT));
url/src/lib.rs:2838: serialization.push('/');
url/src/lib.rs:2839: serialization.extend(percent_encode(component.as_bytes(), PATH_SEGMENT));
url/src/lib.rs:2843: if serialization.len() > host_start
url/src/lib.rs:2844: && parser::is_windows_drive_letter(&serialization[host_start..])
url/src/lib.rs:2847: serialization.push('/');
url/src/lib.rs:2966:// `as_mut_string` string here exposes the internal serialization of an `Url`,
url/src/lib.rs:2978: &mut self.url.as_mut().unwrap().serialization
url/src/path_segments.rs:47: let old_after_path_position = to_u32(url.serialization.len()).unwrap();
url/src/path_segments.rs:50: debug_assert!(url.byte_at(url.path_start) == b'/');
url/src/path_segments.rs:53: url.serialization.len() == url.path_start as usize
url/src/path_segments.rs:54: || url.byte_at(url.path_start) == b'/'
url/src/path_segments.rs:58: after_first_slash: url.path_start as usize + "/".len(),
url/src/path_segments.rs:93: self.url.serialization.truncate(self.after_first_slash);
url/src/path_segments.rs:126: if self.after_first_slash >= self.url.serialization.len() {
url/src/path_segments.rs:129: if self.url.serialization[self.after_first_slash..].ends_with('/') {
url/src/path_segments.rs:130: self.url.serialization.pop();
url/src/path_segments.rs:141: if self.after_first_slash >= self.url.serialization.len() {
url/src/path_segments.rs:144: let last_slash = self.url.serialization[self.after_first_slash..]
url/src/path_segments.rs:148: .serialization
url/src/path_segments.rs:164: /// Each segment is percent-encoded like in `Url::parse` or `Url::join`,
url/src/path_segments.rs:176: /// To obtain a behavior similar to `Url::join`, call `.pop()` unconditionally first.
url/src/path_segments.rs:199: /// In order to make sure that parsing the serialization of an URL gives the same URL,
url/src/path_segments.rs:221: let path_start = self.url.path_start as usize;
url/src/path_segments.rs:229: if parser.serialization.len() > path_start + 1
url/src/path_segments.rs:231: || parser.serialization.len() == path_start
url/src/path_segments.rs:233: parser.serialization.push('/');
url/src/path_segments.rs:239: path_start,
url/src/parser.rs:84: RelativeUrlWithoutBase => "relative URL without a base",
url/src/parser.rs:85: RelativeUrlWithCannotBeABaseBase => "relative URL with a cannot-be-a-base base",
url/src/parser.rs:86: SetHostOnCannotBeABaseUrl => "a cannot-be-a-base URL doesn’t have a host to set",
url/src/parser.rs:322: pub serialization: String,
url/src/parser.rs:351: pub fn for_setter(serialization: String) -> Parser<'a> {
url/src/parser.rs:353: serialization,
url/src/parser.rs:379: self.parse_relative(input, scheme_type, base_url)
url/src/parser.rs:391: debug_assert!(self.serialization.is_empty());
url/src/parser.rs:395: self.serialization.push(c.to_ascii_lowercase())
url/src/parser.rs:399: self.serialization.clear();
url/src/parser.rs:408: self.serialization.clear();
url/src/parser.rs:415: let scheme_end = to_u32(self.serialization.len())?;
url/src/parser.rs:416: let scheme_type = SchemeType::from(&self.serialization);
url/src/parser.rs:417: self.serialization.push(':');
url/src/parser.rs:428: self.serialization.clear();
url/src/parser.rs:432: // special relative or authority state
url/src/parser.rs:436: && base_url.scheme() == &self.serialization[..scheme_end as usize]
url/src/parser.rs:440: self.serialization.clear();
url/src/parser.rs:441: return self.parse_relative(input, scheme_type, base_url);
url/src/parser.rs:470: let path_start = to_u32(self.serialization.len())?;
url/src/parser.rs:471: let username_end = path_start;
url/src/parser.rs:472: let host_start = path_start;
url/src/parser.rs:473: let host_end = path_start;
url/src/parser.rs:477: let path_start = self.serialization.len();
url/src/parser.rs:478: self.serialization.push('/');
url/src/parser.rs:479: self.parse_path(scheme_type, &mut false, path_start, input)
url/src/parser.rs:491: path_start,
url/src/parser.rs:504: debug_assert!(self.serialization.is_empty());
url/src/parser.rs:513: self.serialization.push_str("file://");
url/src/parser.rs:516: let (path_start, mut host, remaining) =
url/src/parser.rs:518: let mut host_end = to_u32(self.serialization.len())?;
url/src/parser.rs:520: let remaining = if path_start {
url/src/parser.rs:521: self.parse_path_start(SchemeType::File, &mut has_host, remaining)
url/src/parser.rs:523: let path_start = self.serialization.len();
url/src/parser.rs:524: self.serialization.push('/');
url/src/parser.rs:525: self.parse_path(SchemeType::File, &mut has_host, path_start, remaining)
url/src/parser.rs:531: self.serialization
url/src/parser.rs:539: serialization: self.serialization,
url/src/parser.rs:546: path_start: host_end,
url/src/parser.rs:551: self.serialization.push_str("file://");
url/src/parser.rs:560: self.serialization.push('/');
url/src/parser.rs:561: self.serialization.push_str(first_segment);
url/src/parser.rs:563: self.serialization.push_str(host_str);
url/src/parser.rs:564: host_end = self.serialization.len();
url/src/parser.rs:590: serialization: self.serialization,
url/src/parser.rs:597: path_start: host_end,
url/src/parser.rs:608: Some(i) => &base_url.serialization[..i as usize],
url/src/parser.rs:609: None => &*base_url.serialization,
url/src/parser.rs:611: self.serialization.push_str(before_fragment);
url/src/parser.rs:613: serialization: self.serialization,
url/src/parser.rs:621: (None, None) => &*base_url.serialization,
url/src/parser.rs:624: self.serialization.push_str(before_query);
url/src/parser.rs:628: serialization: self.serialization,
url/src/parser.rs:638: (None, None) => &*base_url.serialization,
url/src/parser.rs:641: self.serialization.push_str(before_query);
url/src/parser.rs:642: self.shorten_path(SchemeType::File, base_url.path_start as usize);
url/src/parser.rs:646: base_url.path_start as usize,
url/src/parser.rs:657: base_url.path_start,
url/src/parser.rs:661: self.serialization.push_str("file:///");
url/src/parser.rs:663: let path_start = "file://".len();
url/src/parser.rs:665: self.parse_path(SchemeType::File, &mut false, path_start, input);
url/src/parser.rs:668: let path_start = path_start as u32;
url/src/parser.rs:670: serialization: self.serialization,
url/src/parser.rs:672: username_end: path_start,
url/src/parser.rs:673: host_start: path_start,
url/src/parser.rs:674: host_end: path_start,
url/src/parser.rs:677: path_start,
url/src/parser.rs:685: self.serialization.push_str("file:///");
url/src/parser.rs:687: let path_start = "file://".len();
url/src/parser.rs:688: let remaining = self.parse_path(SchemeType::File, &mut false, path_start, input);
url/src/parser.rs:691: let path_start = path_start as u32;
url/src/parser.rs:693: serialization: self.serialization,
url/src/parser.rs:695: username_end: path_start,
url/src/parser.rs:696: host_start: path_start,
url/src/parser.rs:697: host_end: path_start,
url/src/parser.rs:700: path_start,
url/src/parser.rs:707: fn parse_relative(
url/src/parser.rs:713: // relative state
url/src/parser.rs:714: debug_assert!(self.serialization.is_empty());
url/src/parser.rs:720: Some(i) => &base_url.serialization[..i as usize],
url/src/parser.rs:721: None => &*base_url.serialization,
url/src/parser.rs:723: self.serialization.push_str(before_fragment);
url/src/parser.rs:725: serialization: self.serialization,
url/src/parser.rs:733: (None, None) => &*base_url.serialization,
url/src/parser.rs:736: self.serialization.push_str(before_query);
url/src/parser.rs:740: serialization: self.serialization,
url/src/parser.rs:759: self.serialization
url/src/parser.rs:766: let path_start = base_url.path_start;
url/src/parser.rs:767: self.serialization.push_str(base_url.slice(..path_start));
url/src/parser.rs:768: self.serialization.push('/');
url/src/parser.rs:772: path_start as usize,
url/src/parser.rs:783: base_url.path_start,
url/src/parser.rs:789: (None, None) => &*base_url.serialization,
url/src/parser.rs:792: self.serialization.push_str(before_query);
url/src/parser.rs:794: self.pop_path(scheme_type, base_url.path_start as usize);
url/src/parser.rs:797: if self.serialization.len() == base_url.path_start as usize
url/src/parser.rs:800: self.serialization.push('/');
url/src/parser.rs:806: base_url.path_start as usize,
url/src/parser.rs:810: self.parse_path(scheme_type, &mut true, base_url.path_start as usize, input)
url/src/parser.rs:821: base_url.path_start,
url/src/parser.rs:834: self.serialization.push('/');
url/src/parser.rs:835: self.serialization.push('/');
url/src/parser.rs:837: let before_authority = self.serialization.len();
url/src/parser.rs:839: let has_authority = before_authority != self.serialization.len();
url/src/parser.rs:841: let host_start = to_u32(self.serialization.len())?;
url/src/parser.rs:848: let path_start = to_u32(self.serialization.len())?;
url/src/parser.rs:849: let remaining = self.parse_path_start(scheme_type, &mut true, remaining);
url/src/parser.rs:858: path_start,
url/src/parser.rs:889: None => return Ok((to_u32(self.serialization.len())?, input)),
url/src/parser.rs:900: return Ok((to_u32(self.serialization.len())?, remaining));
url/src/parser.rs:913: username_end = Some(to_u32(self.serialization.len())?);
url/src/parser.rs:916: self.serialization.push(':');
url/src/parser.rs:924: self.serialization
url/src/parser.rs:930: None => to_u32(self.serialization.len())?,
url/src/parser.rs:933: self.serialization.push('@');
url/src/parser.rs:945: write!(&mut self.serialization, "{}", host).unwrap();
url/src/parser.rs:946: let host_end = to_u32(self.serialization.len())?;
url/src/parser.rs:960: let scheme = || default_port(&self.serialization[..scheme_end as usize]);
url/src/parser.rs:966: write!(&mut self.serialization, ":{}", port).unwrap()
url/src/parser.rs:1053: write!(&mut self.serialization, "{}", host).unwrap();
url/src/parser.rs:1127: pub fn parse_path_start<'i>(
url/src/parser.rs:1133: let path_start = self.serialization.len();
url/src/parser.rs:1142: if !self.serialization.ends_with('/') {
url/src/parser.rs:1143: self.serialization.push('/');
url/src/parser.rs:1146: return self.parse_path(scheme_type, has_host, path_start, remaining);
url/src/parser.rs:1149: return self.parse_path(scheme_type, has_host, path_start, input);
url/src/parser.rs:1160: self.serialization.push('/');
url/src/parser.rs:1163: self.parse_path(scheme_type, has_host, path_start, input)
url/src/parser.rs:1170: path_start: usize,
url/src/parser.rs:1175: let segment_start = self.serialization.len();
url/src/parser.rs:1186: self.serialization.push(c);
url/src/parser.rs:1194: self.serialization.push('/');
url/src/parser.rs:1206: self.serialization
url/src/parser.rs:1209: self.serialization
url/src/parser.rs:1213: self.serialization.extend(utf8_percent_encode(utf8_c, PATH));
url/src/parser.rs:1219: &self.serialization[segment_start..self.serialization.len() - 1]
url/src/parser.rs:1221: &self.serialization[segment_start..self.serialization.len()]
url/src/parser.rs:1227: debug_assert!(self.serialization.as_bytes()[segment_start - 1] == b'/');
url/src/parser.rs:1228: self.serialization.truncate(segment_start);
url/src/parser.rs:1229: if self.serialization.ends_with('/')
url/src/parser.rs:1230: && Parser::last_slash_can_be_removed(&self.serialization, path_start)
url/src/parser.rs:1232: self.serialization.pop();
url/src/parser.rs:1234: self.shorten_path(scheme_type, path_start);
url/src/parser.rs:1237: if ends_with_slash && !self.serialization.ends_with('/') {
url/src/parser.rs:1238: self.serialization.push('/');
url/src/parser.rs:1244: self.serialization.truncate(segment_start);
url/src/parser.rs:1245: if !self.serialization.ends_with('/') {
url/src/parser.rs:1246: self.serialization.push('/');
url/src/parser.rs:1254: self.serialization.truncate(segment_start);
url/src/parser.rs:1255: self.serialization.push(c);
url/src/parser.rs:1256: self.serialization.push(':');
url/src/parser.rs:1258: self.serialization.push('/');
url/src/parser.rs:1279: let path = self.serialization.split_off(path_start);
url/src/parser.rs:1280: self.serialization.push('/');
url/src/parser.rs:1281: self.serialization.push_str(path.trim_start_matches('/'));
url/src/parser.rs:1287: fn last_slash_can_be_removed(serialization: &str, path_start: usize) -> bool {
url/src/parser.rs:1288: let url_before_segment = &serialization[..serialization.len() - 1];
url/src/parser.rs:1291: segment_before_start >= path_start
url/src/parser.rs:1293: && !path_starts_with_windows_drive_letter(&serialization[segment_before_start..])
url/src/parser.rs:1300: fn shorten_path(&mut self, scheme_type: SchemeType, path_start: usize) {
url/src/parser.rs:1302: if self.serialization.len() == path_start {
url/src/parser.rs:1307: && is_normalized_windows_drive_letter(&self.serialization[path_start..])
url/src/parser.rs:1312: self.pop_path(scheme_type, path_start);
url/src/parser.rs:1316: fn pop_path(&mut self, scheme_type: SchemeType, path_start: usize) {
url/src/parser.rs:1317: if self.serialization.len() > path_start {
url/src/parser.rs:1318: let slash_position = self.serialization[path_start..].rfind('/').unwrap();
url/src/parser.rs:1320: let segment_start = path_start + slash_position + 1;
url/src/parser.rs:1323: && is_normalized_windows_drive_letter(&self.serialization[segment_start..]))
url/src/parser.rs:1325: self.serialization.truncate(segment_start);
url/src/parser.rs:1339: self.serialization
url/src/parser.rs:1357: path_start: u32,
url/src/parser.rs:1363: serialization: self.serialization,
url/src/parser.rs:1370: path_start,
url/src/parser.rs:1387: query_start = Some(to_u32(self.serialization.len())?);
url/src/parser.rs:1388: self.serialization.push('?');
url/src/parser.rs:1400: let fragment_start = to_u32(self.serialization.len())?;
url/src/parser.rs:1401: self.serialization.push('#');
url/src/parser.rs:1425: let encoding = match &self.serialization[..scheme_end as usize] {
url/src/parser.rs:1439: self.serialization.extend(percent_encode(&query_bytes, set));
url/src/parser.rs:1446: None => &*base_url.serialization,
url/src/parser.rs:1448: debug_assert!(self.serialization.is_empty());
url/src/parser.rs:1449: self.serialization
url/src/parser.rs:1451: self.serialization.push_str(before_fragment);
url/src/parser.rs:1452: self.serialization.push('#');
url/src/parser.rs:1457: serialization: self.serialization,
url/src/parser.rs:1470: self.serialization
url/src/parser.rs:1562:fn path_starts_with_windows_drive_letter(s: &str) -> bool {
rg --files
Chunk ID: 8c4498 Wall time: 0.0001 seconds Process exited with code 0 Original token count: 21294 Output: Total output lines: 879 UPGRADING.md idna/Cargo.toml idna/src/make_uts46_mapping_table.py idna/src/uts46.rs idna/src/IdnaMappingTable.txt idna/src/lib.rs idna/src/punycode.rs idna/src/uts46_mapping_table.rs idna/tests/IdnaTestV2.txt idna/tests/uts46.rs idna/tests/punycode_tests.json idna/tests/tests.rs idna/tests/unit.rs idna/tests/punycode.rs idna/benches/all.rs LICENSE-APACHE data-url/Cargo.toml data-url/src/forgiving_base64.rs data-url/src/mime.rs data-url/src/lib.rs data-url/src/make_base64_decode_table.py data-url/tests/data-urls.json data-url/tests/generated-mime-types.json data-url/tests/base64.json data-url/tests/mime-types.json data-url/tests/wpt.rs data-url/README.md debug_metadata/url.natvis debug_metadata/README.md url/Cargo.toml url/src/host.rs url/src/slicing.rs url/src/origin.rs url/src/quirks.rs url/src/lib.rs url/src/path_segments.rs url/src/parser.rs url/tests/data.rs url/tests/setters_tests.json url/tests/urltestdata.json url/tests/unit.rs url/tests/debugger_visualizer.rs url/benches/parse_url.rs url/fuzz/Cargo.toml url/fuzz/fuzz_targets/parse.rs deny.toml LICENSE-MIT form_urlencoded/LICENSE-APACHE form_urlencoded/LICENSE-MIT form_urlencoded/Cargo.toml form_urlencoded/src/lib.rs SECURITY.md Cargo.lock percent_encoding/Cargo.toml percent_encoding/src/lib.rs Cargo.toml README.md target/debug/libpercent_encoding.rlib target/debug/liburl.rlib target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm.lock target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/8gogjfidpjzej9k6cuay2faf8.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/7ut7t8re1b826btusc5cl4v2x.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/agj3f7qghevfxfr23sr28wexi.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/a15dh6016y9308jgv5e47riq3.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/1kxqi2cpw1wo5d2dnndxvf6q3.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/e4mnmm3s16tqamgbh0pqntiok.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/91l4rjlvxicdixq97uw7o70v7.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/02xsfoa6kzjvu1nw0xxho3nlc.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/czcyo95aiasa68gs2u0oxokxg.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/biwxx8v5me9yij2twxhq1ogap.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/bykpo9u62mbxeguwentguhvb0.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/3aei1d9abwc04gi9rd1cvlj2z.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/46oe1q2uzd5akxevv3r99fzip.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/3t3b1o26rvpnv84xk4nmojy1e.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/deq16zjekzu8qul67ogjv8y31.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/9q2hld4yimftwjnk562e1bqew.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/2s6f3kdxqpgxfxyn1rc4xddur.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/dep-graph.bin target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/2775hsj8wkvgpksif3rqwm63w.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/9tkdo65ae4h7m9v8v0ats5of2.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/agq6p4fnfvqm77rbelsw0i4j6.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/work-products.bin target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/5v2gape4c61vc1ddu1kmo158v.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/28zb8h3ry0uxso7421eb3nt2k.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/epqw3gouk3odnxiuj1jo6hldl.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/bowd06t3jgepd1eidi3j9o54c.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/eekib1ye0fmfgef6oigd601yv.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/9whyp654sppd8k0rv4m5xmp82.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/01n2rtdvib90e2jsthfw51efv.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/900gb2yw76l4nrjafed0vh42m.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/a4enno5fp9euzckooxod3npn4.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/eczojs28z19hh99k6eb0g5j04.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/3soable5b906do9pka3x2j9ur.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/9g6iwsh5jtq52d8cdlz8yh4d1.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/3k910szc0dn0ty4qgva8y2qq8.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/4shhir26nlxxq5pss0w47by52.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/258jnbd9zwu7ew57q7u0253aq.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/cnhr8x0pnp7ugoh3ko1u8qs45.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/ee5cxl6a6evr6lsdy0cpxedow.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/3sebt2r12dsn1uk781qs3rnhj.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/bvlmdykgj4xwvt127xupf70rc.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/9phsq551fyex9j1tmbwzj74vr.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/502vo5unbup48b7ifgx6kehad.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/8rohcv8v1088qjcgbuymfy91d.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/0jbs3vebrmgnlpwe60ls7p9uz.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/9b7c6cf9hhtirf46fm6ecyjza.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/amkb38yht8dmwu1xgq03mti1h.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/de3ip26i8gt65m5od9658kn7r.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/2at9epbxsgpyahlfumu7gjq9i.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/899ugj7od0x8px3v3ujykw1p6.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/83ku5vaflgndgid98zhn9tawa.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/5ajzztpqhrapukd0uwkqipsna.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/1fn1lz061zk82vsndz5wj90o3.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/2qgczw6toiaw1fowj9gsqadxt.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/1mqw1yppynw397arbfl65hnkc.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/1ngss9k430ri6t12wx4v9zvcv.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/c7q5qfhogfqcw1j47ilyzo29x.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/csq4p3al5mzznuslat36pej80.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/a801ynq5m11ijqsdjkejvnu0s.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/98ekh76ol0t5gco2kc98r1jcy.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/bva2kc5y142ksiw58kco1di5h.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/cdzafb4i2ma0gvcjzdxxuifs2.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/6dty9q33gde7ehdujwsipdfj4.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/84sswellw3rrji8t4na9w2sdz.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/bgdylkdpa0do687xtaeak4iyx.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/dadh94qizpyp8wrvsgtcggzlp.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/query-cache.bin target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/3e03aiigsd27mupc64rh449kt.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/d4la7jajgpuc26d6ovpq23u1i.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/2ngb3hc1z6qtb06dq5cf3b3gd.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/4meummhxone2t5amg7j24wr07.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/3en08tqxbksbxhaswgqi0sx28.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/9jih05jud875hiz8en3na0y9j.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/dw4jde1xo1n0w2xa4jntnkut0.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/99lgqd3gkfdf8sehcdf25lcgr.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/6thfx2yz1zd3kkquq26m5mo9s.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/86qduwl8ldk65mozdb3lwi113.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/3clpzgo1jabo9s68qdd232jqb.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/4wxyd8q63l2nsrutm7rkca580.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/77wc4bkdzcxbswmtmuaeya94v.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/6m027519o46e4nno9lrqokkpz.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/7gyyqs9cor3i9yfyf4poizv7a.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/3r59joa5o2hnz85fgblg17ylz.o target/debug/incremental/unit-1rtx6ttyceut6/s-hjou0rzxf7-0gprirm-8mmu68kplntmgv5jkthjsnd6n/6adv5em2rxewf6n5fqd8d7m9d.o target/debug/incremental/url-3624ita5ju63y/s-hjou0ruvk4-1a7xc8r-0i4hmo3dzf6r3t8anyfcx7eg7/dep-graph.bin target/debug/incremental/url-3624ita5ju63y/s-hjou0ruvk4-1a7xc8r-0i4hmo3dzf6r3t8anyfcx7eg7/3sfk52cnzdq3lqldqdla1qavt.o target/debug/incremental/url-3624ita5ju63y/s-hjou0ruvk4-1a7xc8r-0i4hmo3dzf6r3t8anyfcx7eg7/work-products.bin target/debug/incremental/url-3624ita5ju63y/s-hjou0ruvk4-1a7xc8r-0i4hmo3dzf6r3t8anyfcx7eg7/8ilh8nwuzeqny6ljn8jbw2i8k.o target/debug/incremental/url-3624ita5ju63y/s-hjou0ruvk4-1a7xc8r-0i4hmo3dzf6r3t8anyfcx7eg7/4l1vm0j7jhztplafysuoeo49c.o target/debug/incremental/url-3624ita5ju63y/s-hjou0ruvk4-1a7xc8r-0i4hmo3dzf6r3t8anyfcx7eg7/5fd3u3mwmlmcw5h6ml7cnji74.o target/debug/incremental/url-3624ita5ju63y/s-hjou0ruvk4-1a7xc8r-0i4hmo3dzf6r3t8anyfcx7eg7/cz3povjitv5meffkbljpcs39v.o target/debug/incremental/url-3624ita5ju63y/s-hjou0ruvk4-1a7xc8r-0i4hmo3dzf6r3t8anyfcx7eg7/query-cache.bin target/debug/incremental/url-3624ita5ju63y/s-hjou0ruvk4-1a7xc8r-0i4hmo3dzf6r3t8anyfcx7eg7/7nwf44ir5vg1i4bia652z894r.o target/debug/incremental/url-3624ita5ju63y/s-hjou0ruvk4-1a7xc8r.lock target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/7cf9q8hxgewy7fxi1c17o9i05.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/9phx5yraspeaqwxoti1fgnsrn.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/04o9cgx8g2kz956ty9tpsgryb.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/5xo60wnqxg5d0zouu0oozzgbk.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/cb9bhzmp64hcwz0i5a2gb7ljo.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/4jj7m0xmf338g0h9ddeavq5tx.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/dep-graph.bin target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/5xerj1fbrybp04odmprzc2tli.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/work-products.bin target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/29coxn26xu0ucq3jceu8oc66m.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/92bdiyw3s2e5mvu7lwkgu6ivr.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/6s6poscwjxwdt5eyd6ym2r70v.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/7sk2a8sic80511hlwuz5hm29c.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/crxgtrgwuh1dtj2ptf8anhy4f.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/clrbht8a7rpj3ovzul6pwl080.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/4zoqbyoi6510ruh1s7ytygswe.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/3ym2vudmm4uwsebtisb6w517c.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/d4bdaewn9b8y4h2bd93722p17.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/afl8quyys9iwv7z3pvotj3q3e.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/emfetx9zqbl9xkryzrm9rd6dy.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/andomrbsvoso3335e5zhcj1yd.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/2n5wgpdggu3o4ey2pwhf1oujx.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/4mu0gd8b6clv6meqa7tzsdrcm.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/cpax00wsrg6ufv6h0tjjsk9ye.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/query-cache.bin target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/8gp07z2d6oe9s1xrjunbtmxij.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/7fu1fneukssvukuu62i6rlgw7.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/by2di4qiusbvp2t42y12c5clj.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/1s91xfp48o921nrv7o90ulx77.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/cqgmz89vl46h02iy47mi6p6c8.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/1lu2c6mxvsput39c4shrvgd2t.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/a887fs7l9anok7yw5qm1tt9wu.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/afn5x3bhw0mdk58dr58txotre.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/9ejwdbt8hw620lzueki5mdy2r.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417-dxiy9q2gpkp9di0h18y73gfd7/878cwrgtzo3vcpcqv4kutl8x3.o target/debug/incremental/unit-31a5kslhf18xu/s-hjou0rfi84-1h7v417.lock target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/9othkraw3qbdb5e9ev5eg5rtq.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/cwa0bj1vggn6xjpkf9nhbt9nt.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/cyujqk6vivgcm8twqp2o31aet.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/24pnjujsglbnpa144imdgykot.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/7twjxl7vvtzau3v8q21uk6x9u.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/5x0z02og4td8p1q4ek7ionbpk.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/cvjal1ffqe3tvi7ugt2tr7s24.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/dep-graph.bin target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/2le4kr196w91zykrbz1u38ldy.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/1zkurdy0ajj5ckboo5dkzjdp5.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/work-products.bin target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/27tkn0dgl56qtoxj7edcfivqp.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/e1at3tiumu08k4o2rzvebe97t.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/3nibda4ow4wvc5gijmqhxw72y.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/9vuil794wxxxynqcxqujejul8.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/0u7qi5ddthljzjcpkfc6ta8tr.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/f18ebq8c8rpbwvkctv3cv57sk.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/ai50witipr45wh5lk17f12bdv.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/6dio3aosr8nplwcwufgppoyhd.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/87igb8wed1g5rk6i2ov4tpsrx.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/5dborrn4nvyw8a2bcp2hs7ixt.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/4n2lprkjg52owqvtd3cs0bm1h.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/query-cache.bin target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/budy2lspdszs5dw7y7iww3mg2.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/el8785gtcnf25tu6awe8kr1wy.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/7wkr8rbqzz5uqwno7nh6bql9j.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/eoqjw13y8h2cc0l8sptxpkgou.o target/debug/incremental/idna-2s4mps90pq4mr/s-hjou0rrsg9-0nrlnq3-0ng4nc93r1nsvdzi5bfrz1y8b/9dvyata0eq51m9lrvm2pikibw.o target/debug/incremental…11294 tokens truncated…l/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/df1d1d6crlbw7skdgc3ra10mk.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/a93155414jj8u3eea9nlhbjz7.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/5u6j1gxxe61aliwm527klnujn.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/1ycfj2jkxq2cv1jkk554tvlih.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/8o05of94ry9hcqubi0igstt4o.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/bmb7llbmjd5v81iwnszfbvq4o.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/3me9m97na6kimdm6mlhkhr9d4.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/4whcma8tc866ma6ncilkczxbc.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/duwjxu5aefho4hz3di6w04uwh.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/query-cache.bin target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/docrj24u4cc71i69idv1gwvg2.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/53m6w1lqbwsu0ti7wzsh9j0wx.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/8efl2q7pm8bc1qe4le1o61j7f.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/7db4aa24j8eocrz5lyrfj0nrw.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/d6uyc7se8s4xqmsosofikoug0.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/bx4juq239lz1f2o9qd9boce6a.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/8m003xfbyn8who1bk030hdjj0.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/0otxrwmc96bn4uvt0dwss9f5z.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/06m80elx0jwoqg06t0fuif9m8.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/dtyuzookd6p0q32oh0d9easrb.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/6dl4gd0nauy0h0fluun719tyy.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8-4lvrqk2ogf09c5qvlidvae53n/4v4x7nrekfjjhm0e5355r9on3.o target/debug/incremental/idna-3i1sdojlmq5rx/s-hjou0p06fa-1bn0oh8.lock target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/5wzecae16rozj4xvouuenar7p.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/01nk6aa7y6c4n95qei4uauc2c.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/1tn6dbouj9ocf0u0fcki0xg0y.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/1b0oszhwrfk9ort5av6gousdu.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/bl4o5nc7vce0sdmo5pok22ota.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/afs0i6s6zv388691vfvc7tg4k.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/2jqul9t1j0l29bjcsy9j37ayj.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/4zs9w75vfddld8oyy4aeopthr.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/00tmlmyaoiygdgu3x4oslkhsr.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/ep3ogarbhnwrb4f2ut39gqh7y.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/2b87v0vqn3q9l0izo8r5lb7rr.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/6u38l4pdqd8wtwu9y3gay7un2.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/7wiv88pynwkcs3oz26bqc2zdn.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/auahwfv40h5q4fyup7qawsbra.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/4bp11qrbx128d1n7b94ffxlh7.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/47umz5htrb05nlsv6sxuajj2p.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/ao1rojs50x143cndr3n4v5t9m.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/45a8639rlanjdlw3lwvpqturb.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/03ud1ta5nt6bo5onx05wv7nta.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/3yaebnp9saivxi52r9m50ntby.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/5gggy3thn3q5nrg6yi5ny0c8o.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/e1l7mvg8dq9y37jibmyat6yve.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/dep-graph.bin target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/5vba5iellj1ulkuqljntrmzs1.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/0zlv7z9v7agtke4me0f6qz3gw.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/ccfea84s964akj2qqwim8ocjb.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/f2vdiqqllaq5wtk9xg9ps21cd.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/work-products.bin target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/3ochkf614g2u2eypuzpzxn22m.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/cfi0y0bi3demeb8yh1oto50br.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/7f4d2d2h0memvcp680bj6kv5o.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/b5znjyqhov28w41kla3x2yrtt.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/e6jnn2isrd4d3hiq9v6upobkz.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/dpw5youu0fyua2nnpu95yskqf.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/89c3zhlh6r5ciygcqfmte97yf.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/ae0huw8sr2g77dmyvpokpukxd.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/eofc15am5mvw5uabmmn4nd8o9.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/btz1iuhouod9yl5u5egoyf94z.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/eieoosrlcam5zwmucqycfydps.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/e8git99ary79gw42aw8ybmswk.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/dw3qknl66f3gu610fnlip9la1.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/daae5zatdxj5g4dc70rps8kz8.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/6zl6275f696c8s2lf9dbo1kfe.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/21bas192pzzii07lv9cy47rpx.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/2oytjtnjol5fulvf4kb3hrt1q.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/7gw86a8st7dcvrgx7zhq8hblx.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/2kfw18f8x0xtd2fg8yqh4hubb.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/dhong62q8nub6llda0n657gvj.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/19ekg3agazwvlhi6hcepc8ucr.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/1ys9ufvderjdl15kgv0sxvox6.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/2nzmsxvj68ou1ddr77w3qxvh6.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/4b9i2pj4jorgkxvxznmyvgp9k.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/3d79sb0ed48sxkyhd3w8cwgu4.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/6jaohicsiotci6m5a5wetay8u.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/9ricz2i5gkxhep945ic5x1dz8.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/85rho75uq1tg22h0yr2kf0imd.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/70m29i3yhdxq069j9c6cpp17l.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/061e7fk3efzxuz21lusjkwjxr.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/f3s1b0yvz2n2dlwyn8zwgpoht.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/5t2k2p0teew9ak0hx0gxea7yk.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/dy0d2diyf9a35hm6s76ym8i1q.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/8w8xtm50dmtxsq8d9g6dei59o.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/f1po4hsqdzml7grw4u5tv1kdp.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/4o1rlyz7bmuue0vqio1fxpdxe.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/egha0hz6c95suwbtpy10bgzi5.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/7p739lxaew3rm6w0vgd9cghu6.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/8pqvrox0kxsj8livgc85c1wg9.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/4ts9s7ewj6hs1mq0wceyckj9f.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/86ekl64ljgriz1xty557eim2h.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/3ctwdlikh71n6j7y9hnpp7i40.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/8qvjw65sfczifk0z4qq1mnfsj.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/query-cache.bin target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/51vfue1hjdjr7o96624o848qh.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/bu32tkdq4dttxi87c4o7fpm9q.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/d6gdt56vgtpwmkqfasmcnl48y.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/cstmfvi5yxnuel06fmtc9r60c.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/dkug62tycjyuwzgs6p260q5i9.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/f27hlljn4o4by4w1d2c3s4tla.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/3tfioxf6o0zfgi3fu6rj1qjqd.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/5z81ap6fkei2j8k4ajp4uh391.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/0rb2siaqtxtqsxe4xnwkv9ud9.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/1dhwbiwuhzrty7ss5lbmezekt.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/3nv95jgd7ldpzicily9exjqzb.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/3w9oxnf1edla6b11tvg2dt3v9.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a-bene5tmkrt5kv2rve6pdxzku1/69apbhc5hjzeydi5782yuhtq5.o target/debug/incremental/url-3cvdemg46jae7/s-hjou0p4irm-1yhu75a.lock target/debug/build/libc-ad25a1021d8bc503/build_script_build-ad25a1021d8bc503 target/debug/build/libc-ad25a1021d8bc503/build_script_build-ad25a1021d8bc503.d target/debug/build/libc-ad25a1021d8bc503/build-script-build target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/7rh446oh9a9qssh1logdl02pd.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/138ywypj0p4hz8c1yzolci8vj.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/8zcz28ufrusxeuzvwrdddqw95.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/4ro337pndi6u8mq3ltkktfamc.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/8r7p6sjrebefmkpstumvn9f7c.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/dep-graph.bin target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/work-products.bin target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/6fd027e4vtb04drzfi3ibc3cy.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/9zrwc851ymvmtfsq2pqpib5uy.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/bkmjsi5y68po5wbn75lpdhupf.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/3985rk03xctcqi5zfib0q9rnq.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/2jum5x7384buq6qoewylcmnds.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/cfln0n5p7ztgntbkcvendyk68.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/cu8ohjtyqfg4mpuwwablueq9e.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/b8khd8v0l61h0tq6h9zykui3a.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/8mep6kq5b8mcakrzy46dileo0.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/3mzt170e2rc0li0bwa4r9dj39.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/query-cache.bin target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/cg8azhw7rv32mkhqq5vbcfg10.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/5lvxv7pmg6atq9ow2okbkke2u.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/5kfjkyy2cf9zqe2ecom52onda.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/73qx2yp1rq54gjsos0laejcub.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/4so737lo0vx00jofsz4ghxjgf.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw-97rveeplqley3535djdbtq0vi/729s4twcw4dvbcpmoh0mrwh8p.o target/debug/incremental/form_urlencoded-00uc8m5pkihl0/s-hjou0ovehp-0w1bekw.lock target/debug/build/serde_core-58ec2e75b87c45d5/build_script_build-58ec2e75b87c45d5.d target/debug/build/serde_core-58ec2e75b87c45d5/build-script-build target/debug/build/serde_core-58ec2e75b87c45d5/build_script_build-58ec2e75b87c45d5 target/debug/build/serde-b1128fd7a9b46781/build_script_build-b1128fd7a9b46781 target/debug/build/serde-b1128fd7a9b46781/build-script-build target/debug/build/serde-b1128fd7a9b46781/build_script_build-b1128fd7a9b46781.d target/debug/build/quote-5b51a8dd8290005e/build_script_build-5b51a8dd8290005e target/debug/build/proc-macro2-4ccecbdd481395e7/build_script_build-4ccecbdd481395e7 target/debug/build/quote-5b51a8dd8290005e/build_script_build-5b51a8dd8290005e.d target/debug/build/proc-macro2-4ccecbdd481395e7/build_script_build-4ccecbdd481395e7.d target/debug/build/proc-macro2-4ccecbdd481395e7/build-script-build target/debug/build/quote-5b51a8dd8290005e/build-script-build target/debug/build/quote-c8e2688b757dd7d5/output target/debug/build/quote-c8e2688b757dd7d5/invoked.timestamp target/debug/build/quote-c8e2688b757dd7d5/stderr target/debug/build/quote-c8e2688b757dd7d5/root-output target/debug/build/syn-543e65d50dac7c38/output target/debug/build/syn-543e65d50dac7c38/invoked.timestamp target/debug/build/syn-543e65d50dac7c38/stderr target/debug/build/syn-543e65d50dac7c38/root-output target/debug/build/syn-255ecb636db8ec71/build_script_build-255ecb636db8ec71 target/debug/build/syn-255ecb636db8ec71/build-script-build target/debug/build/syn-255ecb636db8ec71/build_script_build-255ecb636db8ec71.d target/debug/build/proc-macro2-bd986aab9ef403a2/output target/debug/build/proc-macro2-bd986aab9ef403a2/invoked.timestamp target/debug/build/proc-macro2-bd986aab9ef403a2/stderr target/debug/build/proc-macro2-bd986aab9ef403a2/root-output target/debug/build/serde_core-e64bb9c45bfe80f3/out/private.rs target/debug/build/serde_core-e64bb9c45bfe80f3/output target/debug/build/serde_core-e64bb9c45bfe80f3/invoked.timestamp target/debug/build/serde_core-e64bb9c45bfe80f3/stderr target/debug/build/serde_core-e64bb9c45bfe80f3/root-output target/debug/build/anyhow-865c62892f774c58/build_script_build-865c62892f774c58.d target/debug/build/anyhow-865c62892f774c58/build_script_build-865c62892f774c58 target/debug/build/anyhow-865c62892f774c58/build-script-build target/debug/build/zmij-f4c55d12a4111926/output target/debug/build/libc-6f42403205f9303e/output target/debug/build/zmij-f4c55d12a4111926/invoked.timestamp target/debug/build/zmij-f4c55d12a4111926/stderr target/debug/build/zmij-f4c55d12a4111926/root-output target/debug/build/libc-6f42403205f9303e/invoked.timestamp target/debug/build/libc-6f42403205f9303e/stderr target/debug/build/libc-6f42403205f9303e/root-output target/debug/build/anyhow-7ef9f9965b442394/output target/debug/build/anyhow-7ef9f9965b442394/invoked.timestamp target/debug/build/anyhow-7ef9f9965b442394/stderr target/debug/build/anyhow-7ef9f9965b442394/root-output target/debug/build/serde_json-0ccae1069ea496b1/build_script_build-0ccae1069ea496b1.d target/debug/build/serde_json-0ccae1069ea496b1/build_script_build-0ccae1069ea496b1 target/debug/build/serde_json-0ccae1069ea496b1/build-script-build target/debug/build/zmij-66703644318e2170/build_script_build-66703644318e2170 target/debug/build/zmij-66703644318e2170/build_script_build-66703644318e2170.d target/debug/build/zmij-66703644318e2170/build-script-build target/debug/libdata_url.rlib target/debug/build/serde_json-56a19a2a331ed41b/output target/debug/build/serde_json-56a19a2a331ed41b/invoked.timestamp target/debug/build/serde_json-56a19a2a331ed41b/stderr target/debug/build/serde_json-56a19a2a331ed41b/root-output target/debug/build/serde-ef19f8e495c8dd30/stderr target/debug/build/serde-ef19f8e495c8dd30/root-output target/debug/build/serde-ef19f8e495c8dd30/invoked.timestamp target/debug/build/serde-ef19f8e495c8dd30/output target/debug/build/serde-ef19f8e495c8dd30/out/private.rs
git status --short
Chunk ID: 10fb0d Wall time: 0.0000 seconds Process exited with code 128 Original token count: 18 Output: fatal: not a git repository (or any of the parent directories): .git
sed -n '160,230p' url/src/lib.rs
Chunk ID: e8f432
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 607
Output:
mod origin;
mod parser;
mod path_segments;
mod slicing;
#[doc(hidden)]
pub mod quirks;
/// A parsed URL record.
#[derive(Clone)]
pub struct Url {
/// Syntax in pseudo-BNF:
///
/// url = scheme ":" [ hierarchical | non-hierarchical ] [ "?" query ]? [ "#" fragment ]?
/// non-hierarchical = non-hierarchical-path
/// non-hierarchical-path = /* Does not start with "/" */
/// hierarchical = authority? hierarchical-path
/// authority = "//" userinfo? host [ ":" port ]?
/// userinfo = username [ ":" password ]? "@"
/// hierarchical-path = [ "/" path-segment ]+
serialization: String,
// Components
scheme_end: u32, // Before ':'
username_end: u32, // Before ':' (if a password is given) or '@' (if not)
host_start: u32,
host_end: u32,
host: HostInternal,
port: Option<u16>,
path_start: u32, // Before initial '/', if any
query_start: Option<u32>, // Before '?', unlike Position::QueryStart
fragment_start: Option<u32>, // Before '#', unlike Position::FragmentStart
}
/// Full configuration for the URL parser.
#[derive(Copy, Clone)]
pub struct ParseOptions<'a> {
base_url: Option<&'a Url>,
encoding_override: EncodingOverride<'a>,
violation_fn: Option<&'a dyn Fn(SyntaxViolation)>,
}
impl<'a> ParseOptions<'a> {
/// Change the base URL
pub fn base_url(mut self, new: Option<&'a Url>) -> Self {
self.base_url = new;
self
}
/// Override the character encoding of query strings.
/// This is a legacy concept only relevant for HTML.
pub fn encoding_override(mut self, new: EncodingOverride<'a>) -> Self {
self.encoding_override = new;
self
}
/// Call the provided function or closure for a non-fatal `SyntaxViolation`
/// when it occurs during parsing. Note that since the provided function is
/// `Fn`, the caller might need to utilize _interior mutability_, such as with
/// a `RefCell`, to collect the violations.
///
/// ## Example
/// ```
/// use std::cell::RefCell;
/// use url::{Url, SyntaxViolation};
/// # use url::ParseError;
/// # fn run() -> Result<(), url::ParseError> {
/// let violations = RefCell::new(Vec::new());
/// let url = Url::options()
/// .syntax_violation_callback(Some(&|v| violations.borrow_mut().push(v)))
/// .parse("https:////example.com")?;
sed -n '600,720p' url/src/lib.rs
Chunk ID: 086960
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1275
Output:
/// This is for testing rust-url itself.
#[doc(hidden)]
pub fn check_invariants(&self) -> Result<(), String> {
macro_rules! assert {
($x: expr) => {
if !$x {
return Err(format!(
"!( {} ) for URL {:?}",
stringify!($x),
self.serialization
));
}
};
}
macro_rules! assert_eq {
($a: expr, $b: expr) => {
{
let a = $a;
let b = $b;
if a != b {
return Err(format!("{:?} != {:?} ({} != {}) for URL {:?}",
a, b, stringify!($a), stringify!($b),
self.serialization))
}
}
}
}
assert!(self.scheme_end >= 1);
assert!(self.byte_at(0).is_ascii_alphabetic());
assert!(self
.slice(1..self.scheme_end)
.chars()
.all(|c| matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9' | '+' | '-' | '.')));
assert_eq!(self.byte_at(self.scheme_end), b':');
if self.slice(self.scheme_end + 1..).starts_with("//") {
// URL with authority
if self.username_end != self.serialization.len() as u32 {
match self.byte_at(self.username_end) {
b':' => {
assert!(self.host_start >= self.username_end + 2);
assert_eq!(self.byte_at(self.host_start - 1), b'@');
}
b'@' => assert!(self.host_start == self.username_end + 1),
_ => assert_eq!(self.username_end, self.scheme_end + 3),
}
}
assert!(self.host_start >= self.username_end);
assert!(self.host_end >= self.host_start);
let host_str = self.slice(self.host_start..self.host_end);
match self.host {
HostInternal::None => assert_eq!(host_str, ""),
HostInternal::Ipv4(address) => assert_eq!(host_str, address.to_string()),
HostInternal::Ipv6(address) => {
let h: Host<String> = Host::Ipv6(address);
assert_eq!(host_str, h.to_string())
}
HostInternal::Domain => {
if SchemeType::from(self.scheme()).is_special() {
assert!(!host_str.is_empty())
}
}
}
if self.path_start == self.host_end {
assert_eq!(self.port, None);
} else {
assert_eq!(self.byte_at(self.host_end), b':');
let port_str = self.slice(self.host_end + 1..self.path_start);
assert_eq!(
self.port,
Some(port_str.parse::<u16>().expect("Couldn't parse port?"))
);
}
assert!(
self.path_start as usize == self.serialization.len()
|| matches!(self.byte_at(self.path_start), b'/' | b'#' | b'?')
);
} else {
// Anarchist URL (no authority)
assert_eq!(self.username_end, self.scheme_end + 1);
assert_eq!(self.host_start, self.scheme_end + 1);
assert_eq!(self.host_end, self.scheme_end + 1);
assert_eq!(self.host, HostInternal::None);
assert_eq!(self.port, None);
assert_eq!(self.path_start, self.scheme_end + 1);
}
if let Some(start) = self.query_start {
assert!(start >= self.path_start);
assert_eq!(self.byte_at(start), b'?');
}
if let Some(start) = self.fragment_start {
assert!(start >= self.path_start);
assert_eq!(self.byte_at(start), b'#');
}
if let (Some(query_start), Some(fragment_start)) = (self.query_start, self.fragment_start) {
assert!(fragment_start > query_start);
}
let other = Url::parse(self.as_str()).expect("Failed to parse myself?");
assert_eq!(&self.serialization, &other.serialization);
assert_eq!(self.scheme_end, other.scheme_end);
assert_eq!(self.username_end, other.username_end);
assert_eq!(self.host_start, other.host_start);
assert_eq!(self.host_end, other.host_end);
assert!(
self.host == other.host ||
// XXX No host round-trips to empty host.
// See https://[code-host]/whatwg/url/issues/79
(self.host_str(), other.host_str()) == (None, Some(""))
);
assert_eq!(self.port, other.port);
assert_eq!(self.path_start, other.path_start);
assert_eq!(self.query_start, other.query_start);
assert_eq!(self.fragment_start, other.fragment_start);
Ok(())
}
/// Return the origin of this URL (<https://url.spec.whatwg.org/#origin>)
///
sed -n '1220,1295p' url/src/lib.rs
Chunk ID: a7e9ef
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 727
Output:
//
// > This RFC proposes that *all* type parameters are considered in scope
// > for `impl Trait` in return position
fn io_result<T>(opt: Option<T>, message: &str) -> io::Result<T> {
opt.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, message))
}
let host = io_result(self.host(), "No host name in the URL")?;
let port = io_result(
self.port_or_known_default().or_else(default_port_number),
"No port number in the URL",
)?;
Ok(match host {
Host::Domain(domain) => (domain, port).to_socket_addrs()?.collect(),
Host::Ipv4(ip) => vec![(ip, port).into()],
Host::Ipv6(ip) => vec![(ip, port).into()],
})
}
/// Return the path for this URL, as a percent-encoded ASCII string.
/// For cannot-be-a-base URLs, this is an arbitrary string that doesn’t start with '/'.
/// For other URLs, this starts with a '/' slash
/// and continues with slash-separated path segments.
///
/// # Examples
///
/// ```rust
/// use url::{Url, ParseError};
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("https://example.com/api/versions?page=2")?;
/// assert_eq!(url.path(), "/api/versions");
///
/// let url = Url::parse("https://example.com")?;
/// assert_eq!(url.path(), "/");
///
/// let url = Url::parse("https://example.com/countries/việt nam")?;
/// assert_eq!(url.path(), "/countries/vi%E1%BB%87t%20nam");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn path(&self) -> &str {
match (self.query_start, self.fragment_start) {
(None, None) => self.slice(self.path_start..),
(Some(next_component_start), _) | (None, Some(next_component_start)) => {
self.slice(self.path_start..next_component_start)
}
}
}
/// Unless this URL is cannot-be-a-base,
/// return an iterator of '/' slash-separated path segments,
/// each as a percent-encoded ASCII string.
///
/// Return `None` for cannot-be-a-base URLs.
///
/// When `Some` is returned, the iterator always contains at least one string
/// (which may be empty).
///
/// # Examples
///
/// ```
/// use url::Url;
/// # use std::error::Error;
///
/// # fn run() -> Result<(), Box<dyn Error>> {
/// let url = Url::parse("https://example.com/foo/bar")?;
/// let mut path_segments = url.path_segments().ok_or_else(|| "cannot be base")?;
/// assert_eq!(path_segments.next(), Some("foo"));
/// assert_eq!(path_segments.next(), Some("bar"));
/// assert_eq!(path_segments.next(), None);
///
/// let url = Url::parse("https://example.com")?;
/// let mut path_segments = url.path_segments().ok_or_else(|| "cannot be base")?;
sed -n '80,170p' url/src/slicing.rs
Chunk ID: aa4fea
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 753
Output:
#[derive(Copy, Clone, Debug)]
pub enum Position {
BeforeScheme,
AfterScheme,
BeforeUsername,
AfterUsername,
BeforePassword,
AfterPassword,
BeforeHost,
AfterHost,
BeforePort,
AfterPort,
BeforePath,
AfterPath,
BeforeQuery,
AfterQuery,
BeforeFragment,
AfterFragment,
}
impl Url {
#[inline]
fn index(&self, position: Position) -> usize {
match position {
Position::BeforeScheme => 0,
Position::AfterScheme => self.scheme_end as usize,
Position::BeforeUsername => {
if self.has_authority() {
self.scheme_end as usize + "://".len()
} else {
debug_assert!(self.byte_at(self.scheme_end) == b':');
debug_assert!(self.scheme_end + ":".len() as u32 == self.username_end);
self.scheme_end as usize + ":".len()
}
}
Position::AfterUsername => self.username_end as usize,
Position::BeforePassword => {
if self.has_authority() && self.byte_at(self.username_end) == b':' {
self.username_end as usize + ":".len()
} else {
debug_assert!(self.username_end == self.host_start);
self.username_end as usize
}
}
Position::AfterPassword => {
if self.has_authority() && self.byte_at(self.username_end) == b':' {
debug_assert!(self.byte_at(self.host_start - "@".len() as u32) == b'@');
self.host_start as usize - "@".len()
} else {
debug_assert!(self.username_end == self.host_start);
self.host_start as usize
}
}
Position::BeforeHost => self.host_start as usize,
Position::AfterHost => self.host_end as usize,
Position::BeforePort => {
if self.port.is_some() {
debug_assert!(self.byte_at(self.host_end) == b':');
self.host_end as usize + ":".len()
} else {
self.host_end as usize
}
}
Position::AfterPort => self.path_start as usize,
Position::BeforePath => self.path_start as usize,
Position::AfterPath => match (self.query_start, self.fragment_start) {
(Some(q), _) => q as usize,
(None, Some(f)) => f as usize,
(None, None) => self.serialization.len(),
},
Position::BeforeQuery => match (self.query_start, self.fragment_start) {
(Some(q), _) => {
debug_assert!(self.byte_at(q) == b'?');
q as usize + "?".len()
}
(None, Some(f)) => f as usize,
(None, None) => self.serialization.len(),
},
sed -n '450,505p' url/src/parser.rs
Chunk ID: ebe2e2
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 464
Output:
!= "//"
});
self.after_double_slash(remaining, scheme_type, scheme_end)
}
SchemeType::NotSpecial => self.parse_non_special(input, scheme_type, scheme_end),
}
}
/// Scheme other than file, http, https, ws, ws, ftp.
fn parse_non_special(
mut self,
input: Input<'_>,
scheme_type: SchemeType,
scheme_end: u32,
) -> ParseResult<Url> {
// path or authority state (
if let Some(input) = input.split_prefix("//") {
return self.after_double_slash(input, scheme_type, scheme_end);
}
// Anarchist URL (no authority)
let path_start = to_u32(self.serialization.len())?;
let username_end = path_start;
let host_start = path_start;
let host_end = path_start;
let host = HostInternal::None;
let port = None;
let remaining = if let Some(input) = input.split_prefix('/') {
let path_start = self.serialization.len();
self.serialization.push('/');
self.parse_path(scheme_type, &mut false, path_start, input)
} else {
self.parse_cannot_be_a_base_path(input)
};
self.with_query_and_fragment(
scheme_type,
scheme_end,
username_end,
host_start,
host_end,
host,
port,
path_start,
remaining,
)
}
fn parse_file(
mut self,
input: Input<'_>,
scheme_type: SchemeType,
base_file_url: Option<&Url>,
) -> ParseResult<Url> {
use crate::SyntaxViolation::Backslash;
// file state
debug_assert!(self.serialization.is_empty());
let (first_char, input_after_first_char) = input.split_first();
sed -n '707,825p' url/src/parser.rs
Chunk ID: b959dd
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1321
Output:
fn parse_relative(
mut self,
input: Input<'_>,
scheme_type: SchemeType,
base_url: &Url,
) -> ParseResult<Url> {
// relative state
debug_assert!(self.serialization.is_empty());
let (first_char, input_after_first_char) = input.split_first();
match first_char {
None => {
// Copy everything except the fragment
let before_fragment = match base_url.fragment_start {
Some(i) => &base_url.serialization[..i as usize],
None => &*base_url.serialization,
};
self.serialization.push_str(before_fragment);
Ok(Url {
serialization: self.serialization,
fragment_start: None,
..*base_url
})
}
Some('?') => {
// Copy everything up to the query string
let before_query = match (base_url.query_start, base_url.fragment_start) {
(None, None) => &*base_url.serialization,
(Some(i), _) | (None, Some(i)) => base_url.slice(..i),
};
self.serialization.push_str(before_query);
let (query_start, fragment_start) =
self.parse_query_and_fragment(scheme_type, base_url.scheme_end, input)?;
Ok(Url {
serialization: self.serialization,
query_start,
fragment_start,
..*base_url
})
}
Some('#') => self.fragment_only(base_url, input),
Some('/') | Some('\\') => {
let (slashes_count, remaining) = input.count_matching(|c| matches!(c, '/' | '\\'));
if slashes_count >= 2 {
self.log_violation_if(SyntaxViolation::ExpectedDoubleSlash, || {
input
.clone()
.take_while(|&c| matches!(c, '/' | '\\'))
.collect::<String>()
!= "//"
});
let scheme_end = base_url.scheme_end;
debug_assert!(base_url.byte_at(scheme_end) == b':');
self.serialization
.push_str(base_url.slice(..scheme_end + 1));
if let Some(after_prefix) = input.split_prefix("//") {
return self.after_double_slash(after_prefix, scheme_type, scheme_end);
}
return self.after_double_slash(remaining, scheme_type, scheme_end);
}
let path_start = base_url.path_start;
self.serialization.push_str(base_url.slice(..path_start));
self.serialization.push('/');
let remaining = self.parse_path(
scheme_type,
&mut true,
path_start as usize,
input_after_first_char,
);
self.with_query_and_fragment(
scheme_type,
base_url.scheme_end,
base_url.username_end,
base_url.host_start,
base_url.host_end,
base_url.host,
base_url.port,
base_url.path_start,
remaining,
)
}
_ => {
let before_query = match (base_url.query_start, base_url.fragment_start) {
(None, None) => &*base_url.serialization,
(Some(i), _) | (None, Some(i)) => base_url.slice(..i),
};
self.serialization.push_str(before_query);
// FIXME spec says just "remove last entry", not the "pop" algorithm
self.pop_path(scheme_type, base_url.path_start as usize);
// A special url always has a path.
// A path always starts with '/'
if self.serialization.len() == base_url.path_start as usize
&& (SchemeType::from(base_url.scheme()).is_special() || !input.is_empty())
{
self.serialization.push('/');
}
let remaining = match input.split_first() {
(Some('/'), remaining) => self.parse_path(
scheme_type,
&mut true,
base_url.path_start as usize,
remaining,
),
_ => {
self.parse_path(scheme_type, &mut true, base_url.path_start as usize, input)
}
};
self.with_query_and_fragment(
scheme_type,
base_url.scheme_end,
base_url.username_end,
base_url.host_start,
base_url.host_end,
base_url.host,
base_url.port,
base_url.path_start,
remaining,
)
}
}
sed -n '1120,1290p' url/src/parser.rs
Chunk ID: d892ed
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1964
Output:
let mut opt_port = Some(port as u16);
if !has_any_digit || opt_port == default_port() {
opt_port = None;
}
Ok((opt_port, input))
}
pub fn parse_path_start<'i>(
&mut self,
scheme_type: SchemeType,
has_host: &mut bool,
input: Input<'i>,
) -> Input<'i> {
let path_start = self.serialization.len();
let (maybe_c, remaining) = input.split_first();
// If url is special, then:
if scheme_type.is_special() {
if maybe_c == Some('\\') {
// If c is U+005C (\), validation error.
self.log_violation(SyntaxViolation::Backslash);
}
// A special URL always has a non-empty path.
if !self.serialization.ends_with('/') {
self.serialization.push('/');
// We have already made sure the forward slash is present.
if maybe_c == Some('/') || maybe_c == Some('\\') {
return self.parse_path(scheme_type, has_host, path_start, remaining);
}
}
return self.parse_path(scheme_type, has_host, path_start, input);
} else if maybe_c == Some('?') || maybe_c == Some('#') {
// Otherwise, if state override is not given and c is U+003F (?),
// set url’s query to the empty string and state to query state.
// Otherwise, if state override is not given and c is U+0023 (#),
// set url’s fragment to the empty string and state to fragment state.
// The query and path states will be handled by the caller.
return input;
}
if maybe_c.is_some() && maybe_c != Some('/') {
self.serialization.push('/');
}
// Otherwise, if c is not the EOF code point:
self.parse_path(scheme_type, has_host, path_start, input)
}
pub fn parse_path<'i>(
&mut self,
scheme_type: SchemeType,
has_host: &mut bool,
path_start: usize,
mut input: Input<'i>,
) -> Input<'i> {
// Relative path state
loop {
let segment_start = self.serialization.len();
let mut ends_with_slash = false;
loop {
let input_before_c = input.clone();
let (c, utf8_c) = if let Some(x) = input.next_utf8() {
x
} else {
break;
};
match c {
'/' if self.context != Context::PathSegmentSetter => {
self.serialization.push(c);
ends_with_slash = true;
break;
}
'\\' if self.context != Context::PathSegmentSetter
&& scheme_type.is_special() =>
{
self.log_violation(SyntaxViolation::Backslash);
self.serialization.push('/');
ends_with_slash = true;
break;
}
'?' | '#' if self.context == Context::UrlParser => {
input = input_before_c;
break;
}
_ => {
self.check_url_code_point(c, &input);
if self.context == Context::PathSegmentSetter {
if scheme_type.is_special() {
self.serialization
.extend(utf8_percent_encode(utf8_c, SPECIAL_PATH_SEGMENT));
} else {
self.serialization
.extend(utf8_percent_encode(utf8_c, PATH_SEGMENT));
}
} else {
self.serialization.extend(utf8_percent_encode(utf8_c, PATH));
}
}
}
}
let segment_before_slash = if ends_with_slash {
&self.serialization[segment_start..self.serialization.len() - 1]
} else {
&self.serialization[segment_start..self.serialization.len()]
};
match segment_before_slash {
// If buffer is a double-dot path segment, shorten url’s path,
".." | "%2e%2e" | "%2e%2E" | "%2E%2e" | "%2E%2E" | "%2e." | "%2E." | ".%2e"
| ".%2E" => {
debug_assert!(self.serialization.as_bytes()[segment_start - 1] == b'/');
self.serialization.truncate(segment_start);
if self.serialization.ends_with('/')
&& Parser::last_slash_can_be_removed(&self.serialization, path_start)
{
self.serialization.pop();
}
self.shorten_path(scheme_type, path_start);
// and then if neither c is U+002F (/), nor url is special and c is U+005C (\), append the empty string to url’s path.
if ends_with_slash && !self.serialization.ends_with('/') {
self.serialization.push('/');
}
}
// Otherwise, if buffer is a single-dot path segment and if neither c is U+002F (/),
// nor url is special and c is U+005C (\), append the empty string to url’s path.
"." | "%2e" | "%2E" => {
self.serialization.truncate(segment_start);
if !self.serialization.ends_with('/') {
self.serialization.push('/');
}
}
_ => {
// If url’s scheme is "file", url’s path is empty, and buffer is a Windows drive letter, then
if scheme_type.is_file() && is_windows_drive_letter(segment_before_slash) {
// Replace the second code point in buffer with U+003A (:).
if let Some(c) = segment_before_slash.chars().next() {
self.serialization.truncate(segment_start);
self.serialization.push(c);
self.serialization.push(':');
if ends_with_slash {
self.serialization.push('/');
}
}
// If url’s host is neither the empty string nor null,
// validation error, set url’s host to the empty string.
if *has_host {
self.log_violation(SyntaxViolation::FileWithHostAndWindowsDrive);
*has_host = false; // FIXME account for this in callers
}
}
}
}
if !ends_with_slash {
break;
}
}
if scheme_type.is_file() {
// while url’s path’s size is greater than 1
// and url’s path[0] is the empty string,
// validation error, remove the first item from url’s path.
//FIXME: log violation
let path = self.serialization.split_off(path_start);
self.serialization.push('/');
self.serialization.push_str(path.trim_start_matches('/'));
}
input
}
fn last_slash_can_be_removed(serialization: &str, path_start: usize) -> bool {
let url_before_segment = &serialization[..serialization.len() - 1];
if let Some(segment_before_start) = url_before_segment.rfind('/') {
// Do not remove the root slash
sed -n '1330,1410p' url/src/parser.rs
Chunk ID: 35c380
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 663
Output:
pub fn parse_cannot_be_a_base_path<'i>(&mut self, mut input: Input<'i>) -> Input<'i> {
loop {
let input_before_c = input.clone();
match input.next_utf8() {
Some(('?', _)) | Some(('#', _)) if self.context == Context::UrlParser => {
return input_before_c
}
Some((c, utf8_c)) => {
self.check_url_code_point(c, &input);
self.serialization
.extend(utf8_percent_encode(utf8_c, CONTROLS));
}
None => return input,
}
}
}
#[allow(clippy::too_many_arguments)]
fn with_query_and_fragment(
mut self,
scheme_type: SchemeType,
scheme_end: u32,
username_end: u32,
host_start: u32,
host_end: u32,
host: HostInternal,
port: Option<u16>,
path_start: u32,
remaining: Input<'_>,
) -> ParseResult<Url> {
let (query_start, fragment_start) =
self.parse_query_and_fragment(scheme_type, scheme_end, remaining)?;
Ok(Url {
serialization: self.serialization,
scheme_end,
username_end,
host_start,
host_end,
host,
port,
path_start,
query_start,
fragment_start,
})
}
/// Return (query_start, fragment_start)
fn parse_query_and_fragment(
&mut self,
scheme_type: SchemeType,
scheme_end: u32,
mut input: Input<'_>,
) -> ParseResult<(Option<u32>, Option<u32>)> {
let mut query_start = None;
match input.next() {
Some('#') => {}
Some('?') => {
query_start = Some(to_u32(self.serialization.len())?);
self.serialization.push('?');
let remaining = self.parse_query(scheme_type, scheme_end, input);
if let Some(remaining) = remaining {
input = remaining
} else {
return Ok((query_start, None));
}
}
None => return Ok((None, None)),
_ => panic!("Programming error. parse_query_and_fragment() called without ? or #"),
}
let fragment_start = to_u32(self.serialization.len())?;
self.serialization.push('#');
self.parse_fragment(input);
Ok((query_start, Some(fragment_start)))
}
pub fn parse_query<'i>(
&mut self,
scheme_type: SchemeType,
scheme_end: u32,
mut input: Input<'i>,
sed -n '820,875p' url/src/parser.rs
Chunk ID: f6176c
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 452
Output:
base_url.port,
base_url.path_start,
remaining,
)
}
}
}
fn after_double_slash(
mut self,
input: Input<'_>,
scheme_type: SchemeType,
scheme_end: u32,
) -> ParseResult<Url> {
self.serialization.push('/');
self.serialization.push('/');
// authority state
let before_authority = self.serialization.len();
let (username_end, remaining) = self.parse_userinfo(input, scheme_type)?;
let has_authority = before_authority != self.serialization.len();
// host state
let host_start = to_u32(self.serialization.len())?;
let (host_end, host, port, remaining) =
self.parse_host_and_port(remaining, scheme_end, scheme_type)?;
if host == HostInternal::None && has_authority {
return Err(ParseError::EmptyHost);
}
// path state
let path_start = to_u32(self.serialization.len())?;
let remaining = self.parse_path_start(scheme_type, &mut true, remaining);
self.with_query_and_fragment(
scheme_type,
scheme_end,
username_end,
host_start,
host_end,
host,
port,
path_start,
remaining,
)
}
/// Return (username_end, remaining)
fn parse_userinfo<'i>(
&mut self,
mut input: Input<'i>,
scheme_type: SchemeType,
) -> ParseResult<(u32, Input<'i>)> {
let mut last_at = None;
let mut remaining = input.clone();
let mut char_count = 0;
while let Some(c) = remaining.next() {
match c {
'@' => {
if last_at.is_some() {
sed -n '860,910p' url/src/lib.rs
Chunk ID: 4d1686
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 484
Output:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("unix:/run/foo.socket")?;
/// assert_eq!(url.authority(), "");
/// let url = Url::parse("file:///tmp/foo")?;
/// assert_eq!(url.authority(), "");
/// let url = Url::parse("https://user:password@example.com/tmp/foo")?;
/// assert_eq!(url.authority(), "user:password@example.com");
/// let url = Url::parse("irc://àlex.рф.example.com:6667/foo")?;
/// assert_eq!(url.authority(), "%C3%A0lex.%D1%80%D1%84.example.com:6667");
/// let url = Url::parse("http://àlex.рф.example.com:80/foo")?;
/// assert_eq!(url.authority(), "xn--lex-8ka.xn--p1ai.example.com");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn authority(&self) -> &str {
let scheme_separator_len = "://".len() as u32;
if self.has_authority() && self.path_start > self.scheme_end + scheme_separator_len {
self.slice(self.scheme_end + scheme_separator_len..self.path_start)
} else {
""
}
}
/// Return whether this URL is a cannot-be-a-base URL,
/// meaning that parsing a relative URL string with this URL as the base will return an error.
///
/// This is the case if the scheme and `:` delimiter are not followed by a `/` slash,
/// as is typically the case of `data:` and `mailto:` URLs.
///
/// # Examples
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("ftp://rms@example.com")?;
/// assert!(!url.cannot_be_a_base());
///
/// let url = Url::parse("unix:/run/foo.socket")?;
/// assert!(!url.cannot_be_a_base());
///
/// let url = Url::parse("data:text/plain,Stuff")?;
/// assert!(url.cannot_be_a_base());
/// # Ok(())
sed -n '1600,1685p' url/src/lib.rs
Chunk ID: aaaf4f
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 861
Output:
/// # Examples
///
/// ```rust
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("https://example.com")?;
/// url.set_path("api/comments");
/// assert_eq!(url.as_str(), "https://example.com/api/comments");
/// assert_eq!(url.path(), "/api/comments");
///
/// let mut url = Url::parse("https://example.com/api")?;
/// url.set_path("data/report.csv");
/// assert_eq!(url.as_str(), "https://example.com/data/report.csv");
/// assert_eq!(url.path(), "/data/report.csv");
///
/// // `set_path` percent-encodes the given string if it's not already percent-encoded.
/// let mut url = Url::parse("https://example.com")?;
/// url.set_path("api/some comments");
/// assert_eq!(url.as_str(), "https://example.com/api/some%20comments");
/// assert_eq!(url.path(), "/api/some%20comments");
///
/// // `set_path` will not double percent-encode the string if it's already percent-encoded.
/// let mut url = Url::parse("https://example.com")?;
/// url.set_path("api/some%20comments");
/// assert_eq!(url.as_str(), "https://example.com/api/some%20comments");
/// assert_eq!(url.path(), "/api/some%20comments");
///
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn set_path(&mut self, mut path: &str) {
let after_path = self.take_after_path();
let old_after_path_pos = to_u32(self.serialization.len()).unwrap();
let cannot_be_a_base = self.cannot_be_a_base();
let scheme_type = SchemeType::from(self.scheme());
self.serialization.truncate(self.path_start as usize);
self.mutate(|parser| {
if cannot_be_a_base {
if path.starts_with('/') {
parser.serialization.push_str("%2F");
path = &path[1..];
}
parser.parse_cannot_be_a_base_path(parser::Input::new(path));
} else {
let mut has_host = true; // FIXME
parser.parse_path_start(scheme_type, &mut has_host, parser::Input::new(path));
}
});
self.restore_after_path(old_after_path_pos, &after_path);
}
/// Return an object with methods to manipulate this URL’s path segments.
///
/// Return `Err(())` if this URL is cannot-be-a-base.
#[allow(clippy::result_unit_err)]
pub fn path_segments_mut(&mut self) -> Result<PathSegmentsMut<'_>, ()> {
if self.cannot_be_a_base() {
Err(())
} else {
Ok(path_segments::new(self))
}
}
fn restore_after_path(&mut self, old_after_path_position: u32, after_path: &str) {
let new_after_path_position = to_u32(self.serialization.len()).unwrap();
let adjust = |index: &mut u32| {
*index -= old_after_path_position;
*index += new_after_path_position;
};
if let Some(ref mut index) = self.query_start {
adjust(index)
}
if let Some(ref mut index) = self.fragment_start {
adjust(index)
}
self.serialization.push_str(after_path)
}
/// Change this URL’s port number.
///
/// Note that default port numbers are not reflected in the serialization.
///
/// If this URL is cannot-be-a-base, does not have a host, or has the `file` scheme;
sed -n '1,270p' url/src/path_segments.rs
Chunk ID: b9b209
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2168
Output:
// Copyright 2016 The rust-url developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::parser::{self, to_u32, SchemeType};
use crate::Url;
use std::str;
/// Exposes methods to manipulate the path of an URL that is not cannot-be-base.
///
/// The path always starts with a `/` slash, and is made of slash-separated segments.
/// There is always at least one segment (which may be the empty string).
///
/// Examples:
///
/// ```rust
/// use url::Url;
/// # use std::error::Error;
///
/// # fn run() -> Result<(), Box<dyn Error>> {
/// let mut url = Url::parse("mailto:me@example.com")?;
/// assert!(url.path_segments_mut().is_err());
///
/// let mut url = Url::parse("http://example.net/foo/index.html")?;
/// url.path_segments_mut().map_err(|_| "cannot be base")?
/// .pop().push("img").push("2/100%.png");
/// assert_eq!(url.as_str(), "http://example.net/foo/img/2%2F100%25.png");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
#[derive(Debug)]
pub struct PathSegmentsMut<'a> {
url: &'a mut Url,
after_first_slash: usize,
after_path: String,
old_after_path_position: u32,
}
// Not re-exported outside the crate
pub fn new(url: &mut Url) -> PathSegmentsMut<'_> {
let after_path = url.take_after_path();
let old_after_path_position = to_u32(url.serialization.len()).unwrap();
// Special urls always have a non empty path
if SchemeType::from(url.scheme()).is_special() {
debug_assert!(url.byte_at(url.path_start) == b'/');
} else {
debug_assert!(
url.serialization.len() == url.path_start as usize
|| url.byte_at(url.path_start) == b'/'
);
}
PathSegmentsMut {
after_first_slash: url.path_start as usize + "/".len(),
url,
old_after_path_position,
after_path,
}
}
impl<'a> Drop for PathSegmentsMut<'a> {
fn drop(&mut self) {
self.url
.restore_after_path(self.old_after_path_position, &self.after_path)
}
}
impl<'a> PathSegmentsMut<'a> {
/// Remove all segments in the path, leaving the minimal `url.path() == "/"`.
///
/// Returns `&mut Self` so that method calls can be chained.
///
/// Example:
///
/// ```rust
/// use url::Url;
/// # use std::error::Error;
///
/// # fn run() -> Result<(), Box<dyn Error>> {
/// let mut url = Url::parse("https://[code-host]/servo/rust-url/")?;
/// url.path_segments_mut().map_err(|_| "cannot be base")?
/// .clear().push("logout");
/// assert_eq!(url.as_str(), "https://[code-host]/logout");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn clear(&mut self) -> &mut Self {
self.url.serialization.truncate(self.after_first_slash);
self
}
/// Remove the last segment of this URL’s path if it is empty,
/// except if these was only one segment to begin with.
///
/// In other words, remove one path trailing slash, if any,
/// unless it is also the initial slash (so this does nothing if `url.path() == "/")`.
///
/// Returns `&mut Self` so that method calls can be chained.
///
/// Example:
///
/// ```rust
/// use url::Url;
/// # use std::error::Error;
///
/// # fn run() -> Result<(), Box<dyn Error>> {
/// let mut url = Url::parse("https://[code-host]/servo/rust-url/")?;
/// url.path_segments_mut().map_err(|_| "cannot be base")?
/// .push("pulls");
/// assert_eq!(url.as_str(), "https://[code-host]/servo/rust-url//pulls");
///
/// let mut url = Url::parse("https://[code-host]/servo/rust-url/")?;
/// url.path_segments_mut().map_err(|_| "cannot be base")?
/// .pop_if_empty().push("pulls");
/// assert_eq!(url.as_str(), "https://[code-host]/servo/rust-url/pulls");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn pop_if_empty(&mut self) -> &mut Self {
if self.after_first_slash >= self.url.serialization.len() {
return self;
}
if self.url.serialization[self.after_first_slash..].ends_with('/') {
self.url.serialization.pop();
}
self
}
/// Remove the last segment of this URL’s path.
///
/// If the path only has one segment, make it empty such that `url.path() == "/"`.
///
/// Returns `&mut Self` so that method calls can be chained.
pub fn pop(&mut self) -> &mut Self {
if self.after_first_slash >= self.url.serialization.len() {
return self;
}
let last_slash = self.url.serialization[self.after_first_slash..]
.rfind('/')
.unwrap_or(0);
self.url
.serialization
.truncate(self.after_first_slash + last_slash);
self
}
/// Append the given segment at the end of this URL’s path.
///
/// See the documentation for `.extend()`.
///
/// Returns `&mut Self` so that method calls can be chained.
pub fn push(&mut self, segment: &str) -> &mut Self {
self.extend(Some(segment))
}
/// Append each segment from the given iterator at the end of this URL’s path.
///
/// Each segment is percent-encoded like in `Url::parse` or `Url::join`,
/// except that `%` and `/` characters are also encoded (to `%25` and `%2F`).
/// This is unlike `Url::parse` where `%` is left as-is in case some of the input
/// is already percent-encoded, and `/` denotes a path segment separator.)
///
/// Note that, in addition to slashes between new segments,
/// this always adds a slash between the existing path and the new segments
/// *except* if the existing path is `"/"`.
/// If the previous last segment was empty (if the path had a trailing slash)
/// the path after `.extend()` will contain two consecutive slashes.
/// If that is undesired, call `.pop_if_empty()` first.
///
/// To obtain a behavior similar to `Url::join`, call `.pop()` unconditionally first.
///
/// Returns `&mut Self` so that method calls can be chained.
///
/// Example:
///
/// ```rust
/// use url::Url;
/// # use std::error::Error;
///
/// # fn run() -> Result<(), Box<dyn Error>> {
/// let mut url = Url::parse("https://[code-host]/")?;
/// let org = "servo";
/// let repo = "rust-url";
/// let issue_number = "188";
/// url.path_segments_mut().map_err(|_| "cannot be base")?
/// .extend(&[org, repo, "issues", issue_number]);
/// assert_eq!(url.as_str(), "https://[code-host]/servo/rust-url/issues/188");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// 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;
/// # use std::error::Error;
///
/// # fn run() -> Result<(), Box<dyn Error>> {
/// let mut url = Url::parse("https://[code-host]/servo")?;
/// url.path_segments_mut().map_err(|_| "cannot be base")?
/// .extend(&["..", "rust-url", ".", "pulls"]);
/// assert_eq!(url.as_str(), "https://[code-host]/servo/rust-url/pulls");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
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());
let path_start = self.url.path_start as usize;
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
// Non special url's path might still be empty
|| parser.serialization.len() == path_start
{
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),
);
}
});
self
}
}
rg -n "fn has_authority|has_authority\(" url/src/lib.rs url/src/parser.rs url/src/slicing.rs url/src/quirks.rs url/src/path_segments.rsChunk ID: 02d8dd
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 234
Output:
url/src/lib.rs:831: /// assert!(url.has_authority());
url/src/lib.rs:834: /// assert!(!url.has_authority());
url/src/lib.rs:837: /// assert!(!url.has_authority());
url/src/lib.rs:843: pub fn has_authority(&self) -> bool {
url/src/lib.rs:882: if self.has_authority() && self.path_start > self.scheme_end + scheme_separator_len {
url/src/lib.rs:943: if self.has_authority() && self.username_end > self.scheme_end + scheme_separator_len {
url/src/lib.rs:977: if self.has_authority()
url/src/lib.rs:1948: if !self.has_authority() {
url/src/lib.rs:2326: (new_scheme_type.is_file() && self.has_authority())
url/src/slicing.rs:109: if self.has_authority() {
url/src/slicing.rs:121: if self.has_authority() && self.byte_at(self.username_end) == b':' {
url/src/slicing.rs:130: if self.has_authority() && self.byte_at(self.username_end) == b':' {
sed -n '730,920p' url/src/lib.rs
Chunk ID: 7819a0
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1510
Output:
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("ftp://example.com/foo")?;
/// assert_eq!(url.origin(),
/// Origin::Tuple("ftp".into(),
/// Host::Domain("example.com".into()),
/// 21));
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// URL with `blob` scheme:
///
/// ```rust
/// use url::{Host, Origin, Url};
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("blob:https://example.com/foo")?;
/// assert_eq!(url.origin(),
/// Origin::Tuple("https".into(),
/// Host::Domain("example.com".into()),
/// 443));
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// URL with `file` scheme:
///
/// ```rust
/// use url::{Host, Origin, Url};
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("file:///tmp/foo")?;
/// assert!(!url.origin().is_tuple());
///
/// let other_url = Url::parse("file:///tmp/foo")?;
/// assert!(url.origin() != other_url.origin());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// URL with other scheme:
///
/// ```rust
/// use url::{Host, Origin, Url};
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("foo:bar")?;
/// assert!(!url.origin().is_tuple());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
#[inline]
pub fn origin(&self) -> Origin {
origin::url_origin(self)
}
/// Return the scheme of this URL, lower-cased, as an ASCII string without the ':' delimiter.
///
/// # Examples
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("file:///tmp/foo")?;
/// assert_eq!(url.scheme(), "file");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
#[inline]
pub fn scheme(&self) -> &str {
self.slice(..self.scheme_end)
}
/// Return whether the URL has an 'authority',
/// which can contain a username, password, host, and port number.
///
/// URLs that do *not* are either path-only like `unix:/run/foo.socket`
/// or cannot-be-a-base like `data:text/plain,Stuff`.
///
/// See also the `authority` method.
///
/// # Examples
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("ftp://rms@example.com")?;
/// assert!(url.has_authority());
///
/// let url = Url::parse("unix:/run/foo.socket")?;
/// assert!(!url.has_authority());
///
/// let url = Url::parse("data:text/plain,Stuff")?;
/// assert!(!url.has_authority());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
#[inline]
pub fn has_authority(&self) -> bool {
debug_assert!(self.byte_at(self.scheme_end) == b':');
self.slice(self.scheme_end..).starts_with("://")
}
/// Return the authority of this URL as an ASCII string.
///
/// Non-ASCII domains are punycode-encoded per IDNA if this is the host
/// of a special URL, or percent encoded for non-special URLs.
/// IPv6 addresses are given between `[` and `]` brackets.
/// Ports are omitted if they match the well known port of a special URL.
///
/// Username and password are percent-encoded.
///
/// See also the `has_authority` method.
///
/// # Examples
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("unix:/run/foo.socket")?;
/// assert_eq!(url.authority(), "");
/// let url = Url::parse("file:///tmp/foo")?;
/// assert_eq!(url.authority(), "");
/// let url = Url::parse("https://user:password@example.com/tmp/foo")?;
/// assert_eq!(url.authority(), "user:password@example.com");
/// let url = Url::parse("irc://àlex.рф.example.com:6667/foo")?;
/// assert_eq!(url.authority(), "%C3%A0lex.%D1%80%D1%84.example.com:6667");
/// let url = Url::parse("http://àlex.рф.example.com:80/foo")?;
/// assert_eq!(url.authority(), "xn--lex-8ka.xn--p1ai.example.com");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn authority(&self) -> &str {
let scheme_separator_len = "://".len() as u32;
if self.has_authority() && self.path_start > self.scheme_end + scheme_separator_len {
self.slice(self.scheme_end + scheme_separator_len..self.path_start)
} else {
""
}
}
/// Return whether this URL is a cannot-be-a-base URL,
/// meaning that parsing a relative URL string with this URL as the base will return an error.
///
/// This is the case if the scheme and `:` delimiter are not followed by a `/` slash,
/// as is typically the case of `data:` and `mailto:` URLs.
///
/// # Examples
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("ftp://rms@example.com")?;
/// assert!(!url.cannot_be_a_base());
///
/// let url = Url::parse("unix:/run/foo.socket")?;
/// assert!(!url.cannot_be_a_base());
///
/// let url = Url::parse("data:text/plain,Stuff")?;
/// assert!(url.cannot_be_a_base());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
#[inline]
pub fn cannot_be_a_base(&self) -> bool {
!self.slice(self.scheme_end + 1..).starts_with('/')
}
/// Return the username for this URL (typically the empty string)
/// as a percent-encoded ASCII string.
sed -n '240,360p' url/src/lib.rs
Chunk ID: 0763eb
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 849
Output:
self
}
/// Parse an URL string with the configuration so far.
pub fn parse(self, input: &str) -> Result<Url, crate::ParseError> {
Parser {
serialization: String::with_capacity(input.len()),
base_url: self.base_url,
query_encoding_override: self.encoding_override,
violation_fn: self.violation_fn,
context: Context::UrlParser,
}
.parse_url(input)
}
}
impl Url {
/// Parse an absolute URL from a string.
///
/// # Examples
///
/// ```rust
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("https://example.net")?;
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// # Errors
///
/// If the function can not parse an absolute URL from the given string,
/// a [`ParseError`] variant will be returned.
///
/// [`ParseError`]: enum.ParseError.html
#[inline]
pub fn parse(input: &str) -> Result<Url, crate::ParseError> {
Url::options().parse(input)
}
/// Parse an absolute URL from a string and add params to its query string.
///
/// Existing params are not removed.
///
/// # Examples
///
/// ```rust
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse_with_params("https://example.net?dont=clobberme",
/// &[("lang", "rust"), ("browser", "servo")])?;
/// assert_eq!("https://example.net/?dont=clobberme&lang=rust&browser=servo", url.as_str());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// # Errors
///
/// If the function can not parse an absolute URL from the given string,
/// a [`ParseError`] variant will be returned.
///
/// [`ParseError`]: enum.ParseError.html
#[inline]
pub fn parse_with_params<I, K, V>(input: &str, iter: I) -> Result<Url, crate::ParseError>
where
I: IntoIterator,
I::Item: Borrow<(K, V)>,
K: AsRef<str>,
V: AsRef<str>,
{
let mut url = Url::options().parse(input);
if let Ok(ref mut url) = url {
url.query_pairs_mut().extend_pairs(iter);
}
url
}
/// https://url.spec.whatwg.org/#potentially-strip-trailing-spaces-from-an-opaque-path
fn strip_trailing_spaces_from_opaque_path(&mut self) {
if !self.cannot_be_a_base() {
return;
}
if self.fragment_start.is_some() {
return;
}
if self.query_start.is_some() {
return;
}
let trailing_space_count = self
.serialization
.chars()
.rev()
.take_while(|c| *c == ' ')
.count();
let start = self.serialization.len() - trailing_space_count;
self.serialization.truncate(start);
}
/// Parse a string as an URL, with this URL as the base URL.
///
/// The inverse of this is [`make_relative`].
///
/// Note: a trailing slash is significant.
/// Without it, the last path component is considered to be a “file” name
/// to be removed to get at the “directory” that is used as the base:
///
/// # Examples
///
sed -n '230,310p' url/src/path_segments.rs
Chunk ID: 5a8fb6
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 135
Output:
// Non special url's path might still be empty
|| parser.serialization.len() == path_start
{
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),
);
}
});
self
}
}
rg -n "path_start" url/src/lib.rs url/src/parser.rs url/src/slicing.rs url/src/path_segments.rs url/src/quirks.rs
Chunk ID: 188b3e
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2421
Output:
url/src/parser.rs:470: let path_start = to_u32(self.serialization.len())?;
url/src/parser.rs:471: let username_end = path_start;
url/src/parser.rs:472: let host_start = path_start;
url/src/parser.rs:473: let host_end = path_start;
url/src/parser.rs:477: let path_start = self.serialization.len();
url/src/parser.rs:479: self.parse_path(scheme_type, &mut false, path_start, input)
url/src/parser.rs:491: path_start,
url/src/parser.rs:516: let (path_start, mut host, remaining) =
url/src/parser.rs:520: let remaining = if path_start {
url/src/parser.rs:521: self.parse_path_start(SchemeType::File, &mut has_host, remaining)
url/src/parser.rs:523: let path_start = self.serialization.len();
url/src/parser.rs:525: self.parse_path(SchemeType::File, &mut has_host, path_start, remaining)
url/src/parser.rs:546: path_start: host_end,
url/src/parser.rs:597: path_start: host_end,
url/src/parser.rs:642: self.shorten_path(SchemeType::File, base_url.path_start as usize);
url/src/parser.rs:646: base_url.path_start as usize,
url/src/parser.rs:657: base_url.path_start,
url/src/parser.rs:663: let path_start = "file://".len();
url/src/parser.rs:665: self.parse_path(SchemeType::File, &mut false, path_start, input);
url/src/parser.rs:668: let path_start = path_start as u32;
url/src/parser.rs:672: username_end: path_start,
url/src/parser.rs:673: host_start: path_start,
url/src/parser.rs:674: host_end: path_start,
url/src/parser.rs:677: path_start,
url/src/parser.rs:687: let path_start = "file://".len();
url/src/parser.rs:688: let remaining = self.parse_path(SchemeType::File, &mut false, path_start, input);
url/src/parser.rs:691: let path_start = path_start as u32;
url/src/parser.rs:695: username_end: path_start,
url/src/parser.rs:696: host_start: path_start,
url/src/parser.rs:697: host_end: path_start,
url/src/parser.rs:700: path_start,
url/src/parser.rs:766: let path_start = base_url.path_start;
url/src/parser.rs:767: self.serialization.push_str(base_url.slice(..path_start));
url/src/parser.rs:772: path_start as usize,
url/src/parser.rs:783: base_url.path_start,
url/src/parser.rs:794: self.pop_path(scheme_type, base_url.path_start as usize);
url/src/parser.rs:797: if self.serialization.len() == base_url.path_start as usize
url/src/parser.rs:806: base_url.path_start as usize,
url/src/parser.rs:810: self.parse_path(scheme_type, &mut true, base_url.path_start as usize, input)
url/src/parser.rs:821: base_url.path_start,
url/src/parser.rs:848: let path_start = to_u32(self.serialization.len())?;
url/src/parser.rs:849: let remaining = self.parse_path_start(scheme_type, &mut true, remaining);
url/src/parser.rs:858: path_start,
url/src/parser.rs:1127: pub fn parse_path_start<'i>(
url/src/parser.rs:1133: let path_start = self.serialization.len();
url/src/parser.rs:1146: return self.parse_path(scheme_type, has_host, path_start, remaining);
url/src/parser.rs:1149: return self.parse_path(scheme_type, has_host, path_start, input);
url/src/parser.rs:1163: self.parse_path(scheme_type, has_host, path_start, input)
url/src/parser.rs:1170: path_start: usize,
url/src/parser.rs:1230: && Parser::last_slash_can_be_removed(&self.serialization, path_start)
url/src/parser.rs:1234: self.shorten_path(scheme_type, path_start);
url/src/parser.rs:1279: let path = self.serialization.split_off(path_start);
url/src/parser.rs:1287: fn last_slash_can_be_removed(serialization: &str, path_start: usize) -> bool {
url/src/parser.rs:1291: segment_before_start >= path_start
url/src/parser.rs:1293: && !path_starts_with_windows_drive_letter(&serialization[segment_before_start..])
url/src/parser.rs:1300: fn shorten_path(&mut self, scheme_type: SchemeType, path_start: usize) {
url/src/parser.rs:1302: if self.serialization.len() == path_start {
url/src/parser.rs:1307: && is_normalized_windows_drive_letter(&self.serialization[path_start..])
url/src/parser.rs:1312: self.pop_path(scheme_type, path_start);
url/src/parser.rs:1316: fn pop_path(&mut self, scheme_type: SchemeType, path_start: usize) {
url/src/parser.rs:1317: if self.serialization.len() > path_start {
url/src/parser.rs:1318: let slash_position = self.serialization[path_start..].rfind('/').unwrap();
url/src/parser.rs:1320: let segment_start = path_start + slash_position + 1;
url/src/parser.rs:1357: path_start: u32,
url/src/parser.rs:1370: path_start,
url/src/parser.rs:1562:fn path_starts_with_windows_drive_letter(s: &str) -> bool {
url/src/path_segments.rs:50: debug_assert!(url.byte_at(url.path_start) == b'/');
url/src/path_segments.rs:53: url.serialization.len() == url.path_start as usize
url/src/path_segments.rs:54: || url.byte_at(url.path_start) == b'/'
url/src/path_segments.rs:58: after_first_slash: url.path_start as usize + "/".len(),
url/src/path_segments.rs:221: let path_start = self.url.path_start as usize;
url/src/path_segments.rs:229: if parser.serialization.len() > path_start + 1
url/src/path_segments.rs:231: || parser.serialization.len() == path_start
url/src/path_segments.rs:239: path_start,
url/src/quirks.rs:23:/// | | | | | `----------------- path_start
url/src/quirks.rs:37: pub path_start: u32,
url/src/quirks.rs:54: path_start: url.path_start,
url/src/lib.rs:189: path_start: u32, // Before initial '/', if any
url/src/lib.rs:665: if self.path_start == self.host_end {
url/src/lib.rs:669: let port_str = self.slice(self.host_end + 1..self.path_start);
url/src/lib.rs:676: self.path_start as usize == self.serialization.len()
url/src/lib.rs:677: || matches!(self.byte_at(self.path_start), b'/' | b'#' | b'?')
url/src/lib.rs:686: assert_eq!(self.path_start, self.scheme_end + 1);
url/src/lib.rs:689: assert!(start >= self.path_start);
url/src/lib.rs:693: assert!(start >= self.path_start);
url/src/lib.rs:713: assert_eq!(self.path_start, other.path_start);
url/src/lib.rs:882: if self.has_authority() && self.path_start > self.scheme_end + scheme_separator_len {
url/src/lib.rs:883: self.slice(self.scheme_end + scheme_separator_len..self.path_start)
url/src/lib.rs:1265: (None, None) => self.slice(self.path_start..),
url/src/lib.rs:1267: self.slice(self.path_start..next_component_start)
url/src/lib.rs:1638: self.serialization.truncate(self.path_start as usize);
url/src/lib.rs:1648: parser.parse_path_start(scheme_type, &mut has_host, parser::Input::new(path));
url/src/lib.rs:1759: .drain(self.host_end as usize..self.path_start as usize);
url/src/lib.rs:1760: let offset = self.path_start - self.host_end;
url/src/lib.rs:1761: self.path_start = self.host_end;
url/src/lib.rs:1771: let path_and_after = self.slice(self.path_start..).to_owned();
url/src/lib.rs:1774: let old_path_start = self.path_start;
url/src/lib.rs:1775: let new_path_start = to_u32(self.serialization.len()).unwrap();
url/src/lib.rs:1776: self.path_start = new_path_start;
url/src/lib.rs:1778: *index -= old_path_start;
url/src/lib.rs:1779: *index += new_path_start;
url/src/lib.rs:1909: } else if self.serialization.len() == self.path_start as usize {
url/src/lib.rs:1913: debug_assert!(self.byte_at(self.path_start) == b'/');
url/src/lib.rs:1915: let new_path_start = if scheme_type.is_file() {
url/src/lib.rs:1922: .drain(new_path_start as usize..self.path_start as usize);
url/src/lib.rs:1923: let offset = self.path_start - new_path_start;
url/src/lib.rs:1924: self.path_start = new_path_start;
url/src/lib.rs:1925: self.username_end = new_path_start;
url/src/lib.rs:1926: self.host_start = new_path_start;
url/src/lib.rs:1927: self.host_end = new_path_start;
url/src/lib.rs:1942: self.path_start
url/src/lib.rs:1973: adjust(&mut self.path_start);
url/src/lib.rs:2081: adjust(&mut self.path_start);
url/src/lib.rs:2106: self.path_start -= offset;
url/src/lib.rs:2194: adjust(&mut self.path_start);
url/src/lib.rs:2345: adjust(&mut self.path_start);
url/src/lib.rs:2407: path_start: host_end,
url/src/lib.rs:2463: ref path_start,
url/src/lib.rs:2475: path_start,
url/src/lib.rs:2503: path_start,
url/src/lib.rs:2515: path_start,
url/src/slicing.rs:152: Position::AfterPort => self.path_start as usize,
url/src/slicing.rs:154: Position::BeforePath => self.path_start as usize,
sed -n '930,1035p' url/src/lib.rs
Chunk ID: 88a8c7
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 872
Output:
/// assert_eq!(url.username(), "rms");
///
/// let url = Url::parse("ftp://:secret123@example.com")?;
/// assert_eq!(url.username(), "");
///
/// let url = Url::parse("https://example.com")?;
/// assert_eq!(url.username(), "");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn username(&self) -> &str {
let scheme_separator_len = "://".len() as u32;
if self.has_authority() && self.username_end > self.scheme_end + scheme_separator_len {
self.slice(self.scheme_end + scheme_separator_len..self.username_end)
} else {
""
}
}
/// Return the password for this URL, if any, as a percent-encoded ASCII string.
///
/// # Examples
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("ftp://rms:secret123@example.com")?;
/// assert_eq!(url.password(), Some("secret123"));
///
/// let url = Url::parse("ftp://:secret123@example.com")?;
/// assert_eq!(url.password(), Some("secret123"));
///
/// let url = Url::parse("ftp://rms@example.com")?;
/// assert_eq!(url.password(), None);
///
/// let url = Url::parse("https://example.com")?;
/// assert_eq!(url.password(), None);
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn password(&self) -> Option<&str> {
// This ':' is not the one marking a port number since a host can not be empty.
// (Except for file: URLs, which do not have port numbers.)
if self.has_authority()
&& self.username_end != self.serialization.len() as u32
&& self.byte_at(self.username_end) == b':'
{
debug_assert!(self.byte_at(self.host_start - 1) == b'@');
Some(self.slice(self.username_end + 1..self.host_start - 1))
} else {
None
}
}
/// Equivalent to `url.host().is_some()`.
///
/// # Examples
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("ftp://rms@example.com")?;
/// assert!(url.has_host());
///
/// let url = Url::parse("unix:/run/foo.socket")?;
/// assert!(!url.has_host());
///
/// let url = Url::parse("data:text/plain,Stuff")?;
/// assert!(!url.has_host());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn has_host(&self) -> bool {
!matches!(self.host, HostInternal::None)
}
/// Return the string representation of the host (domain or IP address) for this URL, if any.
///
/// Non-ASCII domains are punycode-encoded per IDNA if this is the host
/// of a special URL, or percent encoded for non-special URLs.
/// IPv6 addresses are given between `[` and `]` brackets.
///
/// Cannot-be-a-base URLs (typical of `data:` and `mailto:`) and some `file:` URLs
/// don’t have a host.
///
/// See also the `host` method.
///
/// # Examples
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("https://127.0.0.1/index.html")?;
/// assert_eq!(url.host_str(), Some("127.0.0.1"));
///
/// let url = Url::parse("ftp://rms@example.com")?;
/// assert_eq!(url.host_str(), Some("example.com"));
sed -n '1400,1585p' url/src/lib.rs
Chunk ID: 601f0b
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1670
Output:
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("https://example.com/data.csv#row=4")?;
///
/// assert_eq!(url.fragment(), Some("row=4"));
///
/// let url = Url::parse("https://example.com/data.csv#cell=4,1-6,2")?;
///
/// assert_eq!(url.fragment(), Some("cell=4,1-6,2"));
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn fragment(&self) -> Option<&str> {
self.fragment_start.map(|start| {
debug_assert!(self.byte_at(start) == b'#');
self.slice(start + 1..)
})
}
fn mutate<F: FnOnce(&mut Parser<'_>) -> R, R>(&mut self, f: F) -> R {
let mut parser = Parser::for_setter(mem::take(&mut self.serialization));
let result = f(&mut parser);
self.serialization = parser.serialization;
result
}
/// Change this URL’s fragment identifier.
///
/// # Examples
///
/// ```rust
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("https://example.com/data.csv")?;
/// assert_eq!(url.as_str(), "https://example.com/data.csv");
/// url.set_fragment(Some("cell=4,1-6,2"));
/// assert_eq!(url.as_str(), "https://example.com/data.csv#cell=4,1-6,2");
/// assert_eq!(url.fragment(), Some("cell=4,1-6,2"));
///
/// url.set_fragment(None);
/// assert_eq!(url.as_str(), "https://example.com/data.csv");
/// assert!(url.fragment().is_none());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn set_fragment(&mut self, fragment: Option<&str>) {
// Remove any previous fragment
if let Some(start) = self.fragment_start {
debug_assert!(self.byte_at(start) == b'#');
self.serialization.truncate(start as usize);
}
// Write the new one
if let Some(input) = fragment {
self.fragment_start = Some(to_u32(self.serialization.len()).unwrap());
self.serialization.push('#');
self.mutate(|parser| parser.parse_fragment(parser::Input::no_trim(input)))
} else {
self.fragment_start = None;
self.strip_trailing_spaces_from_opaque_path();
}
}
fn take_fragment(&mut self) -> Option<String> {
self.fragment_start.take().map(|start| {
debug_assert!(self.byte_at(start) == b'#');
let fragment = self.slice(start + 1..).to_owned();
self.serialization.truncate(start as usize);
fragment
})
}
fn restore_already_parsed_fragment(&mut self, fragment: Option<String>) {
if let Some(ref fragment) = fragment {
assert!(self.fragment_start.is_none());
self.fragment_start = Some(to_u32(self.serialization.len()).unwrap());
self.serialization.push('#');
self.serialization.push_str(fragment);
}
}
/// Change this URL’s query string.
///
/// # Examples
///
/// ```rust
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("https://example.com/products")?;
/// assert_eq!(url.as_str(), "https://example.com/products");
///
/// url.set_query(Some("page=2"));
/// assert_eq!(url.as_str(), "https://example.com/products?page=2");
/// assert_eq!(url.query(), Some("page=2"));
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn set_query(&mut self, query: Option<&str>) {
let fragment = self.take_fragment();
// Remove any previous query
if let Some(start) = self.query_start.take() {
debug_assert!(self.byte_at(start) == b'?');
self.serialization.truncate(start as usize);
}
// Write the new query, if any
if let Some(input) = query {
self.query_start = Some(to_u32(self.serialization.len()).unwrap());
self.serialization.push('?');
let scheme_type = SchemeType::from(self.scheme());
let scheme_end = self.scheme_end;
self.mutate(|parser| {
let vfn = parser.violation_fn;
parser.parse_query(
scheme_type,
scheme_end,
parser::Input::trim_tab_and_newlines(input, vfn),
)
});
} else {
self.query_start = None;
self.strip_trailing_spaces_from_opaque_path();
}
self.restore_already_parsed_fragment(fragment);
}
/// Manipulate this URL’s query string, viewed as a sequence of name/value pairs
/// in `application/x-www-form-urlencoded` syntax.
///
/// The return value has a method-chaining API:
///
/// ```rust
/// # use url::{Url, ParseError};
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("https://example.net?lang=fr#nav")?;
/// assert_eq!(url.query(), Some("lang=fr"));
///
/// url.query_pairs_mut().append_pair("foo", "bar");
/// assert_eq!(url.query(), Some("lang=fr&foo=bar"));
/// assert_eq!(url.as_str(), "https://example.net/?lang=fr&foo=bar#nav");
///
/// url.query_pairs_mut()
/// .clear()
/// .append_pair("foo", "bar & baz")
/// .append_pair("saisons", "\u{00C9}t\u{00E9}+hiver");
/// assert_eq!(url.query(), Some("foo=bar+%26+baz&saisons=%C3%89t%C3%A9%2Bhiver"));
/// assert_eq!(url.as_str(),
/// "https://example.net/?foo=bar+%26+baz&saisons=%C3%89t%C3%A9%2Bhiver#nav");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// Note: `url.query_pairs_mut().clear();` is equivalent to `url.set_query(Some(""))`,
/// not `url.set_query(None)`.
///
/// The state of `Url` is unspecified if this return value is leaked without being dropped.
pub fn query_pairs_mut(&mut self) -> form_urlencoded::Serializer<'_, UrlQuery<'_>> {
let fragment = self.take_fragment();
let query_start;
if let Some(start) = self.query_start {
debug_assert!(self.byte_at(start) == b'?');
query_start = start as usize;
} else {
query_start = self.serialization.len();
self.query_start = Some(to_u32(query_start).unwrap());
self.serialization.push('?');
}
let query = UrlQuery {
url: Some(self),
fragment,
};
form_urlencoded::Serializer::for_suffix(query, query_start + "?".len())
}
sed -n '1720,1980p' url/src/lib.rs
Chunk ID: 59df7b
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2303
Output:
/// # run().unwrap();
/// ```
///
/// Cannot set port for cannot-be-a-base URLs:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("mailto:rms@example.net")?;
///
/// let result = url.set_port(Some(80));
/// assert!(result.is_err());
///
/// let result = url.set_port(None);
/// assert!(result.is_err());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
#[allow(clippy::result_unit_err)]
pub fn set_port(&mut self, mut port: Option<u16>) -> Result<(), ()> {
// has_host implies !cannot_be_a_base
if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
return Err(());
}
if port.is_some() && port == parser::default_port(self.scheme()) {
port = None
}
self.set_port_internal(port);
Ok(())
}
fn set_port_internal(&mut self, port: Option<u16>) {
match (self.port, port) {
(None, None) => {}
(Some(_), None) => {
self.serialization
.drain(self.host_end as usize..self.path_start as usize);
let offset = self.path_start - self.host_end;
self.path_start = self.host_end;
if let Some(ref mut index) = self.query_start {
*index -= offset
}
if let Some(ref mut index) = self.fragment_start {
*index -= offset
}
}
(Some(old), Some(new)) if old == new => {}
(_, Some(new)) => {
let path_and_after = self.slice(self.path_start..).to_owned();
self.serialization.truncate(self.host_end as usize);
write!(&mut self.serialization, ":{}", new).unwrap();
let old_path_start = self.path_start;
let new_path_start = to_u32(self.serialization.len()).unwrap();
self.path_start = new_path_start;
let adjust = |index: &mut u32| {
*index -= old_path_start;
*index += new_path_start;
};
if let Some(ref mut index) = self.query_start {
adjust(index)
}
if let Some(ref mut index) = self.fragment_start {
adjust(index)
}
self.serialization.push_str(&path_and_after);
}
}
self.port = port;
}
/// Change this URL’s host.
///
/// Removing the host (calling this with `None`)
/// will also remove any username, password, and port number.
///
/// # Examples
///
/// Change host:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("https://example.net")?;
/// let result = url.set_host(Some("rust-lang.org"));
/// assert!(result.is_ok());
/// assert_eq!(url.as_str(), "https://rust-lang.org/");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// Remove host:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("foo://example.net")?;
/// let result = url.set_host(None);
/// assert!(result.is_ok());
/// assert_eq!(url.as_str(), "foo:/");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// Cannot remove host for 'special' schemes (e.g. `http`):
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("https://example.net")?;
/// let result = url.set_host(None);
/// assert!(result.is_err());
/// assert_eq!(url.as_str(), "https://example.net/");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// Cannot change or remove host for cannot-be-a-base URLs:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("mailto:rms@example.net")?;
///
/// let result = url.set_host(Some("rust-lang.org"));
/// assert!(result.is_err());
/// assert_eq!(url.as_str(), "mailto:rms@example.net");
///
/// let result = url.set_host(None);
/// assert!(result.is_err());
/// assert_eq!(url.as_str(), "mailto:rms@example.net");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// # Errors
///
/// If this URL is cannot-be-a-base or there is an error parsing the given `host`,
/// a [`ParseError`] variant will be returned.
///
/// [`ParseError`]: enum.ParseError.html
pub fn set_host(&mut self, host: Option<&str>) -> Result<(), ParseError> {
if self.cannot_be_a_base() {
return Err(ParseError::SetHostOnCannotBeABaseUrl);
}
let scheme_type = SchemeType::from(self.scheme());
if let Some(host) = host {
if host.is_empty() && scheme_type.is_special() && !scheme_type.is_file() {
return Err(ParseError::EmptyHost);
}
let mut host_substr = host;
// Otherwise, if c is U+003A (:) and the [] flag is unset, then
if !host.starts_with('[') || !host.ends_with(']') {
match host.find(':') {
Some(0) => {
// If buffer is the empty string, validation error, return failure.
return Err(ParseError::InvalidDomainCharacter);
}
// Let host be the result of host parsing buffer
Some(colon_index) => {
host_substr = &host[..colon_index];
}
None => {}
}
}
if SchemeType::from(self.scheme()).is_special() {
self.set_host_internal(Host::parse(host_substr)?, None);
} else {
self.set_host_internal(Host::parse_opaque(host_substr)?, None);
}
} else if self.has_host() {
if scheme_type.is_special() && !scheme_type.is_file() {
return Err(ParseError::EmptyHost);
} else if self.serialization.len() == self.path_start as usize {
self.serialization.push('/');
}
debug_assert!(self.byte_at(self.scheme_end) == b':');
debug_assert!(self.byte_at(self.path_start) == b'/');
let new_path_start = if scheme_type.is_file() {
self.scheme_end + 3
} else {
self.scheme_end + 1
};
self.serialization
.drain(new_path_start as usize..self.path_start as usize);
let offset = self.path_start - new_path_start;
self.path_start = new_path_start;
self.username_end = new_path_start;
self.host_start = new_path_start;
self.host_end = new_path_start;
self.port = None;
if let Some(ref mut index) = self.query_start {
*index -= offset
}
if let Some(ref mut index) = self.fragment_start {
*index -= offset
}
}
Ok(())
}
/// opt_new_port: None means leave unchanged, Some(None) means remove any port number.
fn set_host_internal(&mut self, host: Host<String>, opt_new_port: Option<Option<u16>>) {
let old_suffix_pos = if opt_new_port.is_some() {
self.path_start
} else {
self.host_end
};
let suffix = self.slice(old_suffix_pos..).to_owned();
self.serialization.truncate(self.host_start as usize);
if !self.has_authority() {
debug_assert!(self.slice(self.scheme_end..self.host_start) == ":");
debug_assert!(self.username_end == self.host_start);
self.serialization.push('/');
self.serialization.push('/');
self.username_end += 2;
self.host_start += 2;
}
write!(&mut self.serialization, "{}", host).unwrap();
self.host_end = to_u32(self.serialization.len()).unwrap();
self.host = host.into();
if let Some(new_port) = opt_new_port {
self.port = new_port;
if let Some(port) = new_port {
write!(&mut self.serialization, ":{}", port).unwrap();
}
}
let new_suffix_pos = to_u32(self.serialization.len()).unwrap();
self.serialization.push_str(&suffix);
let adjust = |index: &mut u32| {
*index -= old_suffix_pos;
*index += new_suffix_pos;
};
adjust(&mut self.path_start);
if let Some(ref mut index) = self.query_start {
adjust(index)
}
if let Some(ref mut index) = self.fragment_start {
adjust(index)
}
}
sed -n '2440,2525p' url/src/lib.rs
Chunk ID: de26b8
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 668
Output:
/// Serialize with Serde using the internal representation of the `Url` struct.
///
/// The corresponding `deserialize_internal` method sacrifices some invariant-checking
/// for speed, compared to the `Deserialize` trait impl.
///
/// This method is only available if the `serde` Cargo feature is enabled.
#[cfg(feature = "serde")]
#[deny(unused)]
pub fn serialize_internal<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::Serialize;
// Destructuring first lets us ensure that adding or removing fields forces this method
// to be updated
let Url {
ref serialization,
ref scheme_end,
ref username_end,
ref host_start,
ref host_end,
ref host,
ref port,
ref path_start,
ref query_start,
ref fragment_start,
} = *self;
(
serialization,
scheme_end,
username_end,
host_start,
host_end,
host,
port,
path_start,
query_start,
fragment_start,
)
.serialize(serializer)
}
/// Serialize with Serde using the internal representation of the `Url` struct.
///
/// The corresponding `deserialize_internal` method sacrifices some invariant-checking
/// for speed, compared to the `Deserialize` trait impl.
///
/// This method is only available if the `serde` Cargo feature is enabled.
#[cfg(feature = "serde")]
#[deny(unused)]
pub fn deserialize_internal<'de, D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::{Deserialize, Error, Unexpected};
let (
serialization,
scheme_end,
username_end,
host_start,
host_end,
host,
port,
path_start,
query_start,
fragment_start,
) = Deserialize::deserialize(deserializer)?;
let url = Url {
serialization,
scheme_end,
username_end,
host_start,
host_end,
host,
port,
path_start,
query_start,
fragment_start,
};
if cfg!(debug_assertions) {
url.check_invariants().map_err(|reason| {
let reason: &str = &reason;
Error::invalid_value(Unexpected::Other("value"), &reason)
})?
}
Ok(url)
rg -n "fn take_after_path|take_after_path" url/src/lib.rs url/src/path_segments.rs
Chunk ID: e50152
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 52
Output:
url/src/path_segments.rs:46: let after_path = url.take_after_path();
url/src/lib.rs:1587: fn take_after_path(&mut self) -> String {
url/src/lib.rs:1634: let after_path = self.take_after_path();
sed -n '1580,1625p' url/src/lib.rs
Chunk ID: b65eb6
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 434
Output:
let query = UrlQuery {
url: Some(self),
fragment,
};
form_urlencoded::Serializer::for_suffix(query, query_start + "?".len())
}
fn take_after_path(&mut self) -> String {
match (self.query_start, self.fragment_start) {
(Some(i), _) | (None, Some(i)) => {
let after_path = self.slice(i..).to_owned();
self.serialization.truncate(i as usize);
after_path
}
(None, None) => String::new(),
}
}
/// Change this URL’s path.
///
/// # Examples
///
/// ```rust
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("https://example.com")?;
/// url.set_path("api/comments");
/// assert_eq!(url.as_str(), "https://example.com/api/comments");
/// assert_eq!(url.path(), "/api/comments");
///
/// let mut url = Url::parse("https://example.com/api")?;
/// url.set_path("data/report.csv");
/// assert_eq!(url.as_str(), "https://example.com/data/report.csv");
/// assert_eq!(url.path(), "/data/report.csv");
///
/// // `set_path` percent-encodes the given string if it's not already percent-encoded.
/// let mut url = Url::parse("https://example.com")?;
/// url.set_path("api/some comments");
/// assert_eq!(url.as_str(), "https://example.com/api/some%20comments");
/// assert_eq!(url.path(), "/api/some%20comments");
///
/// // `set_path` will not double percent-encode the string if it's already percent-encoded.
/// let mut url = Url::parse("https://example.com")?;
/// url.set_path("api/some%20comments");
sed -n '1980,2210p' url/src/lib.rs
Chunk ID: 52dce3
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2086
Output:
}
/// Change this URL’s host to the given IP address.
///
/// If this URL is cannot-be-a-base, do nothing and return `Err`.
///
/// Compared to `Url::set_host`, this skips the host parser.
///
/// # Examples
///
/// ```rust
/// use url::{Url, ParseError};
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("http://example.com")?;
/// url.set_ip_host("127.0.0.1".parse().unwrap());
/// assert_eq!(url.host_str(), Some("127.0.0.1"));
/// assert_eq!(url.as_str(), "http://127.0.0.1/");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// Cannot change URL's from mailto(cannot-be-base) to ip:
///
/// ```rust
/// use url::{Url, ParseError};
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("mailto:rms@example.com")?;
/// let result = url.set_ip_host("127.0.0.1".parse().unwrap());
///
/// assert_eq!(url.as_str(), "mailto:rms@example.com");
/// assert!(result.is_err());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
#[allow(clippy::result_unit_err)]
pub fn set_ip_host(&mut self, address: IpAddr) -> Result<(), ()> {
if self.cannot_be_a_base() {
return Err(());
}
let address = match address {
IpAddr::V4(address) => Host::Ipv4(address),
IpAddr::V6(address) => Host::Ipv6(address),
};
self.set_host_internal(address, None);
Ok(())
}
/// Change this URL’s password.
///
/// If this URL is cannot-be-a-base or does not have a host, do nothing and return `Err`.
///
/// # Examples
///
/// ```rust
/// use url::{Url, ParseError};
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("mailto:rmz@example.com")?;
/// let result = url.set_password(Some("secret_password"));
/// assert!(result.is_err());
///
/// let mut url = Url::parse("ftp://user1:secret1@example.com")?;
/// let result = url.set_password(Some("secret_password"));
/// assert_eq!(url.password(), Some("secret_password"));
///
/// let mut url = Url::parse("ftp://user2:@example.com")?;
/// let result = url.set_password(Some("secret2"));
/// assert!(result.is_ok());
/// assert_eq!(url.password(), Some("secret2"));
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
#[allow(clippy::result_unit_err)]
pub fn set_password(&mut self, password: Option<&str>) -> Result<(), ()> {
// has_host implies !cannot_be_a_base
if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
return Err(());
}
if let Some(password) = password {
let host_and_after = self.slice(self.host_start..).to_owned();
self.serialization.truncate(self.username_end as usize);
self.serialization.push(':');
self.serialization
.extend(utf8_percent_encode(password, USERINFO));
self.serialization.push('@');
let old_host_start = self.host_start;
let new_host_start = to_u32(self.serialization.len()).unwrap();
let adjust = |index: &mut u32| {
*index -= old_host_start;
*index += new_host_start;
};
self.host_start = new_host_start;
adjust(&mut self.host_end);
adjust(&mut self.path_start);
if let Some(ref mut index) = self.query_start {
adjust(index)
}
if let Some(ref mut index) = self.fragment_start {
adjust(index)
}
self.serialization.push_str(&host_and_after);
} else if self.byte_at(self.username_end) == b':' {
// If there is a password to remove
let has_username_or_password = self.byte_at(self.host_start - 1) == b'@';
debug_assert!(has_username_or_password);
let username_start = self.scheme_end + 3;
let empty_username = username_start == self.username_end;
let start = self.username_end; // Remove the ':'
let end = if empty_username {
self.host_start // Remove the '@' as well
} else {
self.host_start - 1 // Keep the '@' to separate the username from the host
};
self.serialization.drain(start as usize..end as usize);
let offset = end - start;
self.host_start -= offset;
self.host_end -= offset;
self.path_start -= offset;
if let Some(ref mut index) = self.query_start {
*index -= offset
}
if let Some(ref mut index) = self.fragment_start {
*index -= offset
}
}
Ok(())
}
/// Change this URL’s username.
///
/// If this URL is cannot-be-a-base or does not have a host, do nothing and return `Err`.
/// # Examples
///
/// Cannot setup username from mailto(cannot-be-base)
///
/// ```rust
/// use url::{Url, ParseError};
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("mailto:rmz@example.com")?;
/// let result = url.set_username("user1");
/// assert_eq!(url.as_str(), "mailto:rmz@example.com");
/// assert!(result.is_err());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// Setup username to user1
///
/// ```rust
/// use url::{Url, ParseError};
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("ftp://:secre1@example.com/")?;
/// let result = url.set_username("user1");
/// assert!(result.is_ok());
/// assert_eq!(url.username(), "user1");
/// assert_eq!(url.as_str(), "ftp://user1:secre1@example.com/");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
#[allow(clippy::result_unit_err)]
pub fn set_username(&mut self, username: &str) -> Result<(), ()> {
// has_host implies !cannot_be_a_base
if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
return Err(());
}
let username_start = self.scheme_end + 3;
debug_assert!(self.slice(self.scheme_end..username_start) == "://");
if self.slice(username_start..self.username_end) == username {
return Ok(());
}
let after_username = self.slice(self.username_end..).to_owned();
self.serialization.truncate(username_start as usize);
self.serialization
.extend(utf8_percent_encode(username, USERINFO));
let mut removed_bytes = self.username_end;
self.username_end = to_u32(self.serialization.len()).unwrap();
let mut added_bytes = self.username_end;
let new_username_is_empty = self.username_end == username_start;
match (new_username_is_empty, after_username.chars().next()) {
(true, Some('@')) => {
removed_bytes += 1;
self.serialization.push_str(&after_username[1..]);
}
(false, Some('@')) | (_, Some(':')) | (true, _) => {
self.serialization.push_str(&after_username);
}
(false, _) => {
added_bytes += 1;
self.serialization.push('@');
self.serialization.push_str(&after_username);
}
}
let adjust = |index: &mut u32| {
*index -= removed_bytes;
*index += added_bytes;
};
adjust(&mut self.host_start);
adjust(&mut self.host_end);
adjust(&mut self.path_start);
if let Some(ref mut index) = self.query_start {
adjust(index)
}
if let Some(ref mut index) = self.fragment_start {
adjust(index)
}
Ok(())
}
/// Change this URL’s scheme.
///
/// Do nothing and return `Err` under the following circumstances:
///
/// * If the new scheme is not in `[a-zA-Z][a-zA-Z0-9+.-]+`
/// * If this URL is cannot-be-a-base and the new scheme is one of
/// `http`, `https`, `ws`, `wss` or `ftp`
sed -n '2200,2360p' url/src/lib.rs
Chunk ID: c3726e
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1434
Output:
}
Ok(())
}
/// Change this URL’s scheme.
///
/// Do nothing and return `Err` under the following circumstances:
///
/// * If the new scheme is not in `[a-zA-Z][a-zA-Z0-9+.-]+`
/// * If this URL is cannot-be-a-base and the new scheme is one of
/// `http`, `https`, `ws`, `wss` or `ftp`
/// * If either the old or new scheme is `http`, `https`, `ws`,
/// `wss` or `ftp` and the other is not one of these
/// * If the new scheme is `file` and this URL includes credentials
/// or has a non-null port
/// * If this URL's scheme is `file` and its host is empty or null
///
/// See also [the URL specification's section on legal scheme state
/// overrides](https://url.spec.whatwg.org/#scheme-state).
///
/// # Examples
///
/// Change the URL’s scheme from `https` to `http`:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("https://example.net")?;
/// let result = url.set_scheme("http");
/// assert_eq!(url.as_str(), "http://example.net/");
/// assert!(result.is_ok());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
/// Change the URL’s scheme from `foo` to `bar`:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("foo://example.net")?;
/// let result = url.set_scheme("bar");
/// assert_eq!(url.as_str(), "bar://example.net");
/// assert!(result.is_ok());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// Cannot change URL’s scheme from `https` to `foõ`:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("https://example.net")?;
/// let result = url.set_scheme("foõ");
/// assert_eq!(url.as_str(), "https://example.net/");
/// assert!(result.is_err());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
///
/// Cannot change URL’s scheme from `mailto` (cannot-be-a-base) to `https`:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("mailto:rms@example.net")?;
/// let result = url.set_scheme("https");
/// assert_eq!(url.as_str(), "mailto:rms@example.net");
/// assert!(result.is_err());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
/// Cannot change the URL’s scheme from `foo` to `https`:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("foo://example.net")?;
/// let result = url.set_scheme("https");
/// assert_eq!(url.as_str(), "foo://example.net");
/// assert!(result.is_err());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
/// Cannot change the URL’s scheme from `http` to `foo`:
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let mut url = Url::parse("http://example.net")?;
/// let result = url.set_scheme("foo");
/// assert_eq!(url.as_str(), "http://example.net/");
/// assert!(result.is_err());
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
#[allow(clippy::result_unit_err, clippy::suspicious_operation_groupings)]
pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> {
let mut parser = Parser::for_setter(String::new());
let remaining = parser.parse_scheme(parser::Input::new(scheme))?;
let new_scheme_type = SchemeType::from(&parser.serialization);
let old_scheme_type = SchemeType::from(self.scheme());
// If url’s scheme is a special scheme and buffer is not a special scheme, then return.
if (new_scheme_type.is_special() && !old_scheme_type.is_special()) ||
// If url’s scheme is not a special scheme and buffer is a special scheme, then return.
(!new_scheme_type.is_special() && old_scheme_type.is_special()) ||
// If url includes credentials or has a non-null port, and buffer is "file", then return.
// If url’s scheme is "file" and its host is an empty host or null, then return.
(new_scheme_type.is_file() && self.has_authority())
{
return Err(());
}
if !remaining.is_empty() || (!self.has_host() && new_scheme_type.is_special()) {
return Err(());
}
let old_scheme_end = self.scheme_end;
let new_scheme_end = to_u32(parser.serialization.len()).unwrap();
let adjust = |index: &mut u32| {
*index -= old_scheme_end;
*index += new_scheme_end;
};
self.scheme_end = new_scheme_end;
adjust(&mut self.username_end);
adjust(&mut self.host_start);
adjust(&mut self.host_end);
adjust(&mut self.path_start);
if let Some(ref mut index) = self.query_start {
adjust(index)
}
if let Some(ref mut index) = self.fragment_start {
adjust(index)
}
parser.serialization.push_str(self.slice(old_scheme_end..));
self.serialization = parser.serialization;
// Update the port so it can be removed
// If it is the scheme's default
// we don't mind it silently failing
// if there was no port in the first place
let previous_port = self.port();
sed -n '1,220p' url/tests/unit.rs
Chunk ID: 7a3f27
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1744
Output:
// Copyright 2013-2014 The rust-url developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Unit tests
use std::borrow::Cow;
use std::cell::{Cell, RefCell};
use std::net::{Ipv4Addr, Ipv6Addr};
use std::path::{Path, PathBuf};
use url::{form_urlencoded, Host, Origin, Url};
#[test]
fn size() {
use std::mem::size_of;
assert_eq!(size_of::<Url>(), size_of::<Option<Url>>());
}
#[test]
fn test_relative() {
let base: Url = "sc://%C3%B1".parse().unwrap();
let url = base.join("/resources/testharness.js").unwrap();
assert_eq!(url.as_str(), "sc://%C3%B1/resources/testharness.js");
}
#[test]
fn test_relative_empty() {
let base: Url = "sc://%C3%B1".parse().unwrap();
let url = base.join("").unwrap();
assert_eq!(url.as_str(), "sc://%C3%B1");
}
#[test]
fn test_strip_trailing_spaces_from_opaque_path() {
let mut url: Url = "data:space ?query".parse().unwrap();
url.set_query(None);
assert_eq!(url.as_str(), "data:space");
let mut url: Url = "data:space #hash".parse().unwrap();
url.set_fragment(None);
assert_eq!(url.as_str(), "data:space");
}
#[test]
fn test_set_empty_host() {
let mut base: Url = "moz://foo:bar@servo/baz".parse().unwrap();
base.set_username("").unwrap();
assert_eq!(base.as_str(), "moz://:bar@servo/baz");
base.set_host(None).unwrap();
assert_eq!(base.as_str(), "moz:/baz");
base.set_host(Some("servo")).unwrap();
assert_eq!(base.as_str(), "moz://servo/baz");
let mut base: Url = "file://server/share/foo/bar".parse().unwrap();
base.set_host(None).unwrap();
assert_eq!(base.as_str(), "file:///share/foo/bar");
let mut base: Url = "file://server/share/foo/bar".parse().unwrap();
base.set_host(Some("foo")).unwrap();
assert_eq!(base.as_str(), "file://foo/share/foo/bar");
}
#[test]
fn test_set_empty_hostname() {
use url::quirks;
let mut base: Url = "moz://foo@servo/baz".parse().unwrap();
assert!(
quirks::set_hostname(&mut base, "").is_err(),
"setting an empty hostname to a url with a username should fail"
);
base = "moz://:pass@servo/baz".parse().unwrap();
assert!(
quirks::set_hostname(&mut base, "").is_err(),
"setting an empty hostname to a url with a password should fail"
);
base = "moz://servo/baz".parse().unwrap();
quirks::set_hostname(&mut base, "").unwrap();
assert_eq!(base.as_str(), "moz:///baz");
}
macro_rules! assert_from_file_path {
($path: expr) => {
assert_from_file_path!($path, $path)
};
($path: expr, $url_path: expr) => {{
let url = Url::from_file_path(Path::new($path)).unwrap();
assert_eq!(url.host(), None);
assert_eq!(url.path(), $url_path);
assert_eq!(url.to_file_path(), Ok(PathBuf::from($path)));
}};
}
#[test]
fn new_file_paths() {
if cfg!(unix) {
assert_eq!(Url::from_file_path(Path::new("relative")), Err(()));
assert_eq!(Url::from_file_path(Path::new("../relative")), Err(()));
}
if cfg!(windows) {
assert_eq!(Url::from_file_path(Path::new("relative")), Err(()));
assert_eq!(Url::from_file_path(Path::new(r"..\relative")), Err(()));
assert_eq!(Url::from_file_path(Path::new(r"\drive-relative")), Err(()));
assert_eq!(Url::from_file_path(Path::new(r"\\ucn\")), Err(()));
}
if cfg!(unix) {
assert_from_file_path!("/foo/bar");
assert_from_file_path!("/foo/ba\0r", "/foo/ba%00r");
assert_from_file_path!("/foo/ba%00r", "/foo/ba%2500r");
}
}
#[test]
#[cfg(unix)]
fn new_path_bad_utf8() {
use std::ffi::OsStr;
use std::os::unix::prelude::*;
let url = Url::from_file_path(Path::new(OsStr::from_bytes(b"/foo/ba\x80r"))).unwrap();
let os_str = OsStr::from_bytes(b"/foo/ba\x80r");
assert_eq!(url.to_file_path(), Ok(PathBuf::from(os_str)));
}
#[test]
fn new_path_windows_fun() {
if cfg!(windows) {
assert_from_file_path!(r"C:\foo\bar", "/C:/foo/bar");
assert_from_file_path!("C:\\foo\\ba\0r", "/C:/foo/ba%00r");
// Invalid UTF-8
assert!(Url::parse("file:///C:/foo/ba%80r")
.unwrap()
.to_file_path()
.is_err());
// test windows canonicalized path
let path = PathBuf::from(r"\\?\C:\foo\bar");
assert!(Url::from_file_path(path).is_ok());
// Percent-encoded drive letter
let url = Url::parse("file:///C%3A/foo/bar").unwrap();
assert_eq!(url.to_file_path(), Ok(PathBuf::from(r"C:\foo\bar")));
}
}
#[test]
fn new_directory_paths() {
if cfg!(unix) {
assert_eq!(Url::from_directory_path(Path::new("relative")), Err(()));
assert_eq!(Url::from_directory_path(Path::new("../relative")), Err(()));
let url = Url::from_directory_path(Path::new("/foo/bar")).unwrap();
assert_eq!(url.host(), None);
assert_eq!(url.path(), "/foo/bar/");
}
if cfg!(windows) {
assert_eq!(Url::from_directory_path(Path::new("relative")), Err(()));
assert_eq!(Url::from_directory_path(Path::new(r"..\relative")), Err(()));
assert_eq!(
Url::from_directory_path(Path::new(r"\drive-relative")),
Err(())
);
assert_eq!(Url::from_directory_path(Path::new(r"\\ucn\")), Err(()));
let url = Url::from_directory_path(Path::new(r"C:\foo\bar")).unwrap();
assert_eq!(url.host(), None);
assert_eq!(url.path(), "/C:/foo/bar/");
}
}
#[test]
fn path_backslash_fun() {
let mut special_url = "http://foobar.com".parse::<Url>().unwrap();
special_url.path_segments_mut().unwrap().push("foo\\bar");
assert_eq!(special_url.as_str(), "http://foobar.com/foo%5Cbar");
let mut nonspecial_url = "thing://foobar.com".parse::<Url>().unwrap();
nonspecial_url.path_segments_mut().unwrap().push("foo\\bar");
assert_eq!(nonspecial_url.as_str(), "thing://foobar.com/foo\\bar");
}
#[test]
fn from_str() {
assert!("http://testing.com/this".parse::<Url>().is_ok());
}
#[test]
fn parse_with_params() {
let url = Url::parse_with_params(
"http://testing.com/this?dont=clobberme",
&[("lang", "rust")],
)
.unwrap();
assert_eq!(
url.as_str(),
"http://testing.com/this?dont=clobberme&lang=rust"
);
}
#[test]
fn issue_124() {
let url: Url = "file:a".parse().unwrap();
assert_eq!(url.path(), "/a");
let url: Url = "file:...".parse().unwrap();
assert_eq!(url.path(), "/...");
let url: Url = "file:..".parse().unwrap();
assert_eq!(url.path(), "/");
}
#[test]
fn test_equality() {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
fn check_eq(a: &Url, b: &Url) {
tail -n 120 url/tests/unit.rs
Chunk ID: 235688
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1067
Output:
),
(
"http://127.0.0.1:8080/test/?foo=bar#123",
"http://127.0.0.1:8080/test/video",
"video",
),
(
"http://127.0.0.1:8080/test/",
"http://127.0.0.1:8080/test/video?baz=meh#456",
"video?baz=meh#456",
),
(
"http://127.0.0.1:8080/test",
"http://127.0.0.1:8080/test?baz=meh#456",
"?baz=meh#456",
),
(
"http://127.0.0.1:8080/test/",
"http://127.0.0.1:8080/test?baz=meh#456",
"../test?baz=meh#456",
),
(
"http://127.0.0.1:8080/test/",
"http://127.0.0.1:8080/test/?baz=meh#456",
"?baz=meh#456",
),
(
"http://127.0.0.1:8080/test/?foo=bar#123",
"http://127.0.0.1:8080/test/video?baz=meh#456",
"video?baz=meh#456",
),
(
"http://127.0.0.1:8080/file.txt",
"http://127.0.0.1:8080/test/file.txt",
"test/file.txt",
),
(
"http://127.0.0.1:8080/not_equal.txt",
"http://127.0.0.1:8080/test/file.txt",
"test/file.txt",
),
];
for (base, uri, relative) in &tests {
let base_uri = url::Url::parse(base).unwrap();
let relative_uri = url::Url::parse(uri).unwrap();
let make_relative = base_uri.make_relative(&relative_uri).unwrap();
assert_eq!(
make_relative, *relative,
"base: {}, uri: {}, relative: {}",
base, uri, relative
);
assert_eq!(
base_uri.join(relative).unwrap().as_str(),
*uri,
"base: {}, uri: {}, relative: {}",
base,
uri,
relative
);
}
let error_tests = [
("http://127.0.0.1:8080/", "https://127.0.0.1:8080/test/"),
("http://127.0.0.1:8080/", "http://127.0.0.1:8081/test/"),
("http://127.0.0.1:8080/", "http://127.0.0.2:8080/test/"),
("mailto:a@example.com", "mailto:b@example.com"),
];
for (base, uri) in &error_tests {
let base_uri = url::Url::parse(base).unwrap();
let relative_uri = url::Url::parse(uri).unwrap();
let make_relative = base_uri.make_relative(&relative_uri);
assert_eq!(make_relative, None, "base: {}, uri: {}", base, uri);
}
}
#[test]
fn test_has_authority() {
let url = Url::parse("mailto:joe@example.com").unwrap();
assert!(!url.has_authority());
let url = Url::parse("unix:/run/foo.socket").unwrap();
assert!(!url.has_authority());
let url = Url::parse("file:///tmp/foo").unwrap();
assert!(url.has_authority());
let url = Url::parse("http://example.com/tmp/foo").unwrap();
assert!(url.has_authority());
}
#[test]
fn test_authority() {
let url = Url::parse("mailto:joe@example.com").unwrap();
assert_eq!(url.authority(), "");
let url = Url::parse("unix:/run/foo.socket").unwrap();
assert_eq!(url.authority(), "");
let url = Url::parse("file:///tmp/foo").unwrap();
assert_eq!(url.authority(), "");
let url = Url::parse("http://example.com/tmp/foo").unwrap();
assert_eq!(url.authority(), "example.com");
let url = Url::parse("ftp://127.0.0.1:21/").unwrap();
assert_eq!(url.authority(), "127.0.0.1");
let url = Url::parse("ftp://user@127.0.0.1:2121/").unwrap();
assert_eq!(url.authority(), "user@127.0.0.1:2121");
let url = Url::parse("https://:@example.com/").unwrap();
assert_eq!(url.authority(), "example.com");
let url = Url::parse("https://:password@[::1]:8080/").unwrap();
assert_eq!(url.authority(), ":password@[::1]:8080");
let url = Url::parse("gopher://user:@àlex.example.com:70").unwrap();
assert_eq!(url.authority(), "user@%C3%A0lex.example.com:70");
let url = Url::parse("irc://àlex:àlex@àlex.рф.example.com:6667/foo").unwrap();
assert_eq!(
url.authority(),
"%C3%A0lex:%C3%A0lex@%C3%A0lex.%D1%80%D1%84.example.com:6667"
);
let url = Url::parse("https://àlex:àlex@àlex.рф.example.com:443/foo").unwrap();
assert_eq!(
url.authority(),
"%C3%A0lex:%C3%A0lex@xn--lex-8ka.xn--p1ai.example.com"
);
}
*** Begin Patch
*** Update File: /app/url/src/lib.rs
@@
impl Url {
+ fn has_no_authority_components(&self) -> bool {
+ let scheme_end = self.scheme_end + ":".len() as u32;
+ self.username_end == scheme_end
+ && self.host_start == scheme_end
+ && self.host_end == scheme_end
+ && self.host == HostInternal::None
+ && self.port.is_none()
+ }
+
+ pub(crate) fn path_marker_start(&self) -> Option<u32> {
+ if SchemeType::from(self.scheme()).is_special()
+ || !self.has_no_authority_components()
+ || self.path_start < "/.".len() as u32
+ {
+ return None;
+ }
+
+ let marker_start = self.path_start - "/.".len() as u32;
+ if self.slice(marker_start..self.path_start) == "/." && self.path().starts_with("//") {
+ Some(marker_start)
+ } else {
+ None
+ }
+ }
+
+ pub(crate) fn path_start_without_marker(&self) -> u32 {
+ self.path_marker_start().unwrap_or(self.path_start)
+ }
+
+ pub(crate) fn ensure_non_special_path_marker(&mut self) {
+ let marker_start = self.path_marker_start();
+ let needs_marker = !SchemeType::from(self.scheme()).is_special()
+ && self.has_no_authority_components()
+ && self.path().starts_with("//");
+
+ match (needs_marker, marker_start) {
+ (true, None) => {
+ self.serialization
+ .insert_str(self.path_start as usize, "/.");
+ self.path_start += "/.".len() as u32;
+ if let Some(ref mut index) = self.query_start {
+ *index += "/.".len() as u32;
+ }
+ if let Some(ref mut index) = self.fragment_start {
+ *index += "/.".len() as u32;
+ }
+ }
+ (false, Some(marker_start)) => {
+ self.serialization
+ .drain(marker_start as usize..self.path_start as usize);
+ self.path_start = marker_start;
+ if let Some(ref mut index) = self.query_start {
+ *index -= "/.".len() as u32;
+ }
+ if let Some(ref mut index) = self.fragment_start {
+ *index -= "/.".len() as u32;
+ }
+ }
+ _ => {}
+ }
+ }
+
/// Parse an absolute URL from a string.
*** End Patch
Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/url/src/lib.rs
*** Begin Patch
*** Update File: /app/url/src/parser.rs
@@
Some('/') | Some('\\') => {
let (slashes_count, remaining) = input.count_matching(|c| matches!(c, '/' | '\\'));
if slashes_count >= 2 {
@@
return self.after_double_slash(remaining, scheme_type, scheme_end);
}
- let path_start = base_url.path_start;
+ let path_start = base_url.path_start_without_marker();
self.serialization.push_str(base_url.slice(..path_start));
self.serialization.push('/');
let remaining = self.parse_path(
scheme_type,
&mut true,
@@
}
_ => {
- let before_query = match (base_url.query_start, base_url.fragment_start) {
- (None, None) => &*base_url.serialization,
- (Some(i), _) | (None, Some(i)) => base_url.slice(..i),
- };
- self.serialization.push_str(before_query);
+ let path_start = base_url.path_start_without_marker();
+ self.serialization.push_str(base_url.slice(..path_start));
+ self.serialization.push_str(base_url.path());
// FIXME spec says just "remove last entry", not the "pop" algorithm
- self.pop_path(scheme_type, base_url.path_start as usize);
+ self.pop_path(scheme_type, path_start as usize);
// A special url always has a path.
// A path always starts with '/'
- if self.serialization.len() == base_url.path_start as usize
+ if self.serialization.len() == path_start as usize
&& (SchemeType::from(base_url.scheme()).is_special() || !input.is_empty())
{
self.serialization.push('/');
}
let remaining = match input.split_first() {
(Some('/'), remaining) => self.parse_path(
scheme_type,
&mut true,
- base_url.path_start as usize,
+ path_start as usize,
remaining,
),
_ => {
- self.parse_path(scheme_type, &mut true, base_url.path_start as usize, input)
+ self.parse_path(scheme_type, &mut true, path_start as usize, input)
}
};
self.with_query_and_fragment(
scheme_type,
base_url.scheme_end,
@@
base_url.host_start,
base_url.host_end,
base_url.host,
base_url.port,
- base_url.path_start,
+ path_start,
remaining,
)
}
}
}
@@
- let (query_start, fragment_start) =
- self.parse_query_and_fragment(scheme_type, scheme_end, remaining)?;
- Ok(Url {
+ let (query_start, fragment_start) =
+ self.parse_query_and_fragment(scheme_type, scheme_end, remaining)?;
+ let mut url = Url {
serialization: self.serialization,
scheme_end,
username_end,
host_start,
host_end,
@@
path_start,
query_start,
fragment_start,
- })
+ };
+ url.ensure_non_special_path_marker();
+ Ok(url)
}
*** End Patch
Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/url/src/parser.rs
sed -n '750,825p' url/src/parser.rs
Chunk ID: 59b9e9
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 826
Output:
self.log_violation_if(SyntaxViolation::ExpectedDoubleSlash, || {
input
.clone()
.take_while(|&c| matches!(c, '/' | '\\'))
.collect::<String>()
!= "//"
});
let scheme_end = base_url.scheme_end;
debug_assert!(base_url.byte_at(scheme_end) == b':');
self.serialization
.push_str(base_url.slice(..scheme_end + 1));
if let Some(after_prefix) = input.split_prefix("//") {
return self.after_double_slash(after_prefix, scheme_type, scheme_end);
}
return self.after_double_slash(remaining, scheme_type, scheme_end);
}
let path_start = base_url.path_start_without_marker();
self.serialization.push_str(base_url.slice(..path_start));
self.serialization.push('/');
let remaining = self.parse_path(
scheme_type,
&mut true,
path_start as usize,
input_after_first_char,
);
self.with_query_and_fragment(
scheme_type,
base_url.scheme_end,
base_url.username_end,
base_url.host_start,
base_url.host_end,
base_url.host,
base_url.port,
base_url.path_start,
remaining,
)
}
_ => {
let path_start = base_url.path_start_without_marker();
self.serialization.push_str(base_url.slice(..path_start));
self.serialization.push_str(base_url.path());
// FIXME spec says just "remove last entry", not the "pop" algorithm
self.pop_path(scheme_type, path_start as usize);
// A special url always has a path.
// A path always starts with '/'
if self.serialization.len() == path_start as usize
&& (SchemeType::from(base_url.scheme()).is_special() || !input.is_empty())
{
self.serialization.push('/');
}
let remaining = match input.split_first() {
(Some('/'), remaining) => self.parse_path(
scheme_type,
&mut true,
path_start as usize,
remaining,
),
_ => {
self.parse_path(scheme_type, &mut true, path_start as usize, input)
}
};
self.with_query_and_fragment(
scheme_type,
base_url.scheme_end,
base_url.username_end,
base_url.host_start,
base_url.host_end,
base_url.host,
base_url.port,
path_start,
remaining,
)
}
}
}
*** Begin Patch
*** Update File: /app/url/src/parser.rs
@@
base_url.host_start,
base_url.host_end,
base_url.host,
base_url.port,
- base_url.path_start,
+ path_start,
remaining,
)
}
*** End Patch
Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/url/src/parser.rs
*** Begin Patch
*** Update File: /app/url/src/slicing.rs
@@
- Position::AfterPort => self.path_start as usize,
+ Position::AfterPort => self.path_start_without_marker() as usize,
Position::BeforePath => self.path_start as usize,
*** End Patch
Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/url/src/slicing.rs
*** Begin Patch
*** Update File: /app/url/src/lib.rs
@@
- if self.slice(self.scheme_end + 1..).starts_with("//") {
+ if self.has_authority() {
// URL with authority
if self.username_end != self.serialization.len() as u32 {
match self.byte_at(self.username_end) {
@@
} else {
// Anarchist URL (no authority)
assert_eq!(self.username_end, self.scheme_end + 1);
assert_eq!(self.host_start, self.scheme_end + 1);
assert_eq!(self.host_end, self.scheme_end + 1);
assert_eq!(self.host, HostInternal::None);
assert_eq!(self.port, None);
- assert_eq!(self.path_start, self.scheme_end + 1);
+ let path_start_without_marker = self.path_start_without_marker();
+ assert_eq!(path_start_without_marker, self.scheme_end + 1);
+ if self.path_start != path_start_without_marker {
+ assert_eq!(self.slice(path_start_without_marker..self.path_start), "/.");
+ assert!(self.path().starts_with("//"));
+ }
}
*** End Patch
Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/url/src/lib.rs
*** Begin Patch
*** Update File: /app/url/src/lib.rs
@@
let after_path = self.take_after_path();
let old_after_path_pos = to_u32(self.serialization.len()).unwrap();
let cannot_be_a_base = self.cannot_be_a_base();
let scheme_type = SchemeType::from(self.scheme());
- self.serialization.truncate(self.path_start as usize);
+ let path_start = self.path_start_without_marker();
+ self.serialization.truncate(path_start as usize);
+ self.path_start = path_start;
self.mutate(|parser| {
if cannot_be_a_base {
if path.starts_with('/') {
parser.serialization.push_str("%2F");
path = &path[1..];
@@
parser.parse_path_start(scheme_type, &mut has_host, parser::Input::new(path));
}
});
+ self.ensure_non_special_path_marker();
self.restore_after_path(old_after_path_pos, &after_path);
}
*** End Patch
Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/url/src/lib.rs
*** Begin Patch
*** Update File: /app/url/src/path_segments.rs
@@
impl<'a> Drop for PathSegmentsMut<'a> {
fn drop(&mut self) {
+ self.url.ensure_non_special_path_marker();
self.url
.restore_after_path(self.old_after_path_position, &self.after_path)
}
}
*** End Patch
Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/url/src/path_segments.rs
*** Begin Patch
*** Update File: /app/url/src/lib.rs
@@
if let Some(ref mut index) = self.fragment_start {
*index -= offset
}
+ self.ensure_non_special_path_marker();
}
Ok(())
}
@@
/// opt_new_port: None means leave unchanged, Some(None) means remove any port number.
fn set_host_internal(&mut self, host: Host<String>, opt_new_port: Option<Option<u16>>) {
let old_suffix_pos = if opt_new_port.is_some() {
self.path_start
+ } else if self.path_marker_start().is_some() {
+ self.path_start
} else {
self.host_end
};
*** End Patch
Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/url/src/lib.rs
*** Begin Patch
*** Update File: /app/url/tests/unit.rs
@@
-use url::{form_urlencoded, Host, Origin, Url};
+use url::{form_urlencoded, Host, Origin, Position, Url};
@@
fn test_relative_empty() {
let base: Url = "sc://%C3%B1".parse().unwrap();
let url = base.join("").unwrap();
assert_eq!(url.as_str(), "sc://%C3%B1");
}
+
+#[test]
+fn non_special_path_starting_with_double_slash_uses_marker() {
+ let url = Url::parse("foo:/.//example/path?query#fragment").unwrap();
+ assert_eq!(url.as_str(), "foo:/.//example/path?query#fragment");
+ assert!(!url.has_authority());
+ assert_eq!(url.host_str(), None);
+ assert_eq!(url.path(), "//example/path");
+ assert_eq!(url.query(), Some("query"));
+ assert_eq!(url.fragment(), Some("fragment"));
+ assert_eq!(&url[Position::AfterPort..Position::BeforePath], "/.");
+ assert_eq!(&url[Position::BeforePath..Position::AfterPath], "//example/path");
+
+ let reparsed = Url::parse(url.as_str()).unwrap();
+ assert_eq!(reparsed.as_str(), url.as_str());
+ assert!(!reparsed.has_authority());
+ assert_eq!(reparsed.host_str(), None);
+ assert_eq!(reparsed.path(), "//example/path");
+}
+
+#[test]
+fn non_special_join_recomputes_double_slash_marker() {
+ let base = Url::parse("foo:/.//a/b?old#frag").unwrap();
+
+ let keeps_double_slash = base.join("c").unwrap();
+ assert_eq!(keeps_double_slash.as_str(), "foo:/.//a/c");
+ assert_eq!(keeps_double_slash.path(), "//a/c");
+ assert_eq!(
+ &keeps_double_slash[Position::AfterPort..Position::BeforePath],
+ "/."
+ );
+
+ let removes_marker = base.join("../c").unwrap();
+ assert_eq!(removes_marker.as_str(), "foo:/c");
+ assert_eq!(removes_marker.path(), "/c");
+ assert_eq!(
+ &removes_marker[Position::AfterPort..Position::BeforePath],
+ ""
+ );
+
+ let query_only = base.join("?new").unwrap();
+ assert_eq!(query_only.as_str(), "foo:/.//a/b?new");
+ assert_eq!(query_only.path(), "//a/b");
+
+ let fragment_only = base.join("#new").unwrap();
+ assert_eq!(fragment_only.as_str(), "foo:/.//a/b?old#new");
+ assert_eq!(fragment_only.path(), "//a/b");
+}
+
+#[test]
+fn marker_is_not_used_for_host_bearing_or_special_urls() {
+ let host_url = Url::parse("foo://host//path").unwrap();
+ assert!(host_url.has_authority());
+ assert_eq!(host_url.path(), "//path");
+ assert_eq!(&host_url[Position::AfterPort..Position::BeforePath], "");
+
+ let special = Url::parse("http://example.com//path").unwrap();
+ assert!(special.has_authority());
+ assert_eq!(special.path(), "//path");
+ assert_eq!(&special[Position::AfterPort..Position::BeforePath], "");
+}
*** End Patch
Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/url/tests/unit.rs
cargo test -p url --test unit non_special --locked
Chunk ID: ec4cec
Wall time: 1.9533 seconds
Process exited with code 101
Original token count: 756
Output:
Compiling proc-macro2 v1.0.106
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
--> percent_encoding/src/lib.rs:462:35
|
462 | debug_assert!(raw_utf8 == &*bytes as *const [u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(ambiguous_wide_pointer_comparisons)]` on by default
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
462 | debug_assert!(std::ptr::addr_eq(raw_utf8, &*bytes as *const [u8]));
| ++++++++++++++++++ ~ +
help: use explicit `std::ptr::eq` method to compare metadata and addresses
|
462 | debug_assert!(std::ptr::eq(raw_utf8, &*bytes as *const [u8]));
| +++++++++++++ ~ +
warning: `percent-encoding` (lib) generated 1 warning
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
--> form_urlencoded/src/lib.rs:403:35
|
403 | debug_assert!(raw_utf8 == &*bytes as *const [u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(ambiguous_wide_pointer_comparisons)]` on by default
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
403 | debug_assert!(std::ptr::addr_eq(raw_utf8, &*bytes as *const [u8]));
| ++++++++++++++++++ ~ +
help: use explicit `std::ptr::eq` method to compare metadata and addresses
|
403 | debug_assert!(std::ptr::eq(raw_utf8, &*bytes as *const [u8]));
| +++++++++++++ ~ +
warning: `form_urlencoded` (lib) generated 1 warning
Compiling url v2.3.1 (/app/url)
Compiling quote v1.0.45
Compiling syn v1.0.109
Compiling debugger_test v0.1.5
Finished `test` profile [unoptimized + debuginfo] target(s) in 2.07s
Running tests/unit.rs (target/debug/deps/unit-a494890561398094)
running 5 tests
test non_special_path_starting_with_double_slash_uses_marker ... ok
test non_special_join_recomputes_double_slash_marker ... FAILED
test test_non_special_path ... ok
test test_non_special_path2 ... ok
test test_non_special_path3 ... ok
failures:
---- non_special_join_recomputes_double_slash_marker stdout ----
thread 'non_special_join_recomputes_double_slash_marker' panicked at url/tests/unit.rs:69:5:
assertion `left == right` failed
left: "foo:/.//c"
right: "foo:/c"
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
non_special_join_recomputes_double_slash_marker
test result: FAILED. 4 passed; 1 failed; 0 ignored; 0 measured; 56 filtered out; finished in 0.00s
error: test failed, to rerun pass `-p url --test unit`
*** Begin Patch
*** Update File: /app/url/tests/unit.rs
@@
- let removes_marker = base.join("../c").unwrap();
+ let removes_marker = base.join("../../c").unwrap();
*** End Patch
Exit code: 0
Wall time: 0 seconds
Output:
Success. Updated the following files:
M /app/url/tests/unit.rs
cargo test -p url --test unit non_special --locked
Chunk ID: 56be09
Wall time: 0.1617 seconds
Process exited with code 0
Original token count: 614
Output:
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
--> percent_encoding/src/lib.rs:462:35
|
462 | debug_assert!(raw_utf8 == &*bytes as *const [u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(ambiguous_wide_pointer_comparisons)]` on by default
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
462 | debug_assert!(std::ptr::addr_eq(raw_utf8, &*bytes as *const [u8]));
| ++++++++++++++++++ ~ +
help: use explicit `std::ptr::eq` method to compare metadata and addresses
|
462 | debug_assert!(std::ptr::eq(raw_utf8, &*bytes as *const [u8]));
| +++++++++++++ ~ +
warning: `percent-encoding` (lib) generated 1 warning
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
--> form_urlencoded/src/lib.rs:403:35
|
403 | debug_assert!(raw_utf8 == &*bytes as *const [u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(ambiguous_wide_pointer_comparisons)]` on by default
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
403 | debug_assert!(std::ptr::addr_eq(raw_utf8, &*bytes as *const [u8]));
| ++++++++++++++++++ ~ +
help: use explicit `std::ptr::eq` method to compare metadata and addresses
|
403 | debug_assert!(std::ptr::eq(raw_utf8, &*bytes as *const [u8]));
| +++++++++++++ ~ +
warning: `form_urlencoded` (lib) generated 1 warning
Compiling url v2.3.1 (/app/url)
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.29s
Running tests/unit.rs (target/debug/deps/unit-a494890561398094)
running 5 tests
test non_special_path_starting_with_double_slash_uses_marker ... ok
test non_special_join_recomputes_double_slash_marker ... ok
test test_non_special_path ... ok
test test_non_special_path2 ... ok
test test_non_special_path3 ... ok
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 56 filtered out; finished in 0.00s
cargo fmt
Chunk ID: 7ac349 Wall time: 0.1648 seconds Process exited with code 1 Original token count: 35 Output: error: 'cargo-fmt' is not installed for the toolchain '1.85.1-aarch64-unknown-linux-gnu'. To install, run `rustup component add rustfmt`
cargo build --locked
Chunk ID: ab73f2
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 755
Output:
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
--> percent_encoding/src/lib.rs:462:35
|
462 | debug_assert!(raw_utf8 == &*bytes as *const [u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(ambiguous_wide_pointer_comparisons)]` on by default
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
462 | debug_assert!(std::ptr::addr_eq(raw_utf8, &*bytes as *const [u8]));
| ++++++++++++++++++ ~ +
help: use explicit `std::ptr::eq` method to compare metadata and addresses
|
462 | debug_assert!(std::ptr::eq(raw_utf8, &*bytes as *const [u8]));
| +++++++++++++ ~ +
warning: `percent-encoding` (lib) generated 1 warning
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
--> form_urlencoded/src/lib.rs:403:35
|
403 | debug_assert!(raw_utf8 == &*bytes as *const [u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(ambiguous_wide_pointer_comparisons)]` on by default
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
403 | debug_assert!(std::ptr::addr_eq(raw_utf8, &*bytes as *const [u8]));
| ++++++++++++++++++ ~ +
help: use explicit `std::ptr::eq` method to compare metadata and addresses
|
403 | debug_assert!(std::ptr::eq(raw_utf8, &*bytes as *const [u8]));
| +++++++++++++ ~ +
warning: `form_urlencoded` (lib) generated 1 warning
warning: field `0` is never read
--> data-url/src/forgiving_base64.rs:4:26
|
4 | pub struct InvalidBase64(InvalidBase64Details);
| ------------- ^^^^^^^^^^^^^^^^^^^^
| |
| field in this struct
|
= help: consider removing this field
= note: `InvalidBase64` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
= note: `#[warn(dead_code)]` on by default
warning: field `0` is never read
--> data-url/src/forgiving_base64.rs:8:22
|
8 | UnexpectedSymbol(u8),
| ---------------- ^^
| |
| field in this variant
|
= note: `InvalidBase64Details` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
|
8 | UnexpectedSymbol(()),
| ~~
warning: `data-url` (lib) generated 2 warnings
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
cargo test -p url --locked
Chunk ID: 2b0cb9
Wall time: 3.7202 seconds
Process exited with code 0
Original token count: 2162
Output:
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
--> percent_encoding/src/lib.rs:462:35
|
462 | debug_assert!(raw_utf8 == &*bytes as *const [u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(ambiguous_wide_pointer_comparisons)]` on by default
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
462 | debug_assert!(std::ptr::addr_eq(raw_utf8, &*bytes as *const [u8]));
| ++++++++++++++++++ ~ +
help: use explicit `std::ptr::eq` method to compare metadata and addresses
|
462 | debug_assert!(std::ptr::eq(raw_utf8, &*bytes as *const [u8]));
| +++++++++++++ ~ +
warning: `percent-encoding` (lib) generated 1 warning
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
--> form_urlencoded/src/lib.rs:403:35
|
403 | debug_assert!(raw_utf8 == &*bytes as *const [u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(ambiguous_wide_pointer_comparisons)]` on by default
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
403 | debug_assert!(std::ptr::addr_eq(raw_utf8, &*bytes as *const [u8]));
| ++++++++++++++++++ ~ +
help: use explicit `std::ptr::eq` method to compare metadata and addresses
|
403 | debug_assert!(std::ptr::eq(raw_utf8, &*bytes as *const [u8]));
| +++++++++++++ ~ +
warning: `form_urlencoded` (lib) generated 1 warning
Compiling url v2.3.1 (/app/url)
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.32s
Running unittests src/lib.rs (target/debug/deps/url-2559718008fa8f63)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running tests/data.rs (target/debug/deps/data-2c0f19163cfb41ae)
running 2 tests
test setters_tests ... ok
test urltestdata ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
Running tests/unit.rs (target/debug/deps/unit-a494890561398094)
running 61 tests
test append_empty_segment_then_mutate ... ok
test append_trailing_slash ... ok
test form_urlencoded_encoding_override ... ok
test from_str ... ok
test extend_query_pairs_then_mutate ... ok
test host_serialization ... ok
test issue_124 ... ok
test host ... ok
test issue_197 ... ok
test issue_241 ... ok
test issue_61 ... ok
test marker_is_not_used_for_host_bearing_or_special_urls ... ok
test new_directory_paths ... ok
test new_path_bad_utf8 ... ok
test new_path_windows_fun ... ok
test new_file_paths ... ok
test non_special_join_recomputes_double_slash_marker ... ok
test non_special_path_starting_with_double_slash_uses_marker ... ok
test no_panic ... ok
test parse_with_params ... ok
test path_backslash_fun ... ok
test pop_if_empty_in_bounds ... ok
test size ... ok
test test_domain ... ok
test test_authority ... ok
test test_domain_encoding_quirks ... ok
test test_equality ... ok
test test_form_serialize ... ok
test test_form_urlencoded ... ok
test test_has_authority ... ok
test test_idna ... ok
test test_fragment ... ok
test test_leading_dots ... ok
test test_no_base_url ... ok
test test_non_special_path ... ok
test test_non_special_path2 ... ok
test test_make_relative ... ok
test test_non_special_path3 ... ok
test test_options_reuse ... ok
test test_origin_blob_equality ... ok
test test_origin_hash ... ok
test test_origin_opaque ... ok
test test_query ... ok
test test_relative ... ok
test test_origin_unicode_serialization ... ok
test test_relative_empty ... ok
test test_serialization ... ok
test test_set_empty_host ... ok
test test_set_empty_hostname ... ok
test test_set_href ... ok
test test_set_host ... ok
test test_set_ip_host ... ok
test test_set_scheme_to_file_with_host ... ok
test test_slicing ... ok
test test_strip_trailing_spaces_from_opaque_path ... ok
test test_syntax_violation_callback ... ok
test test_syntax_violation_callback_lifetimes ... ok
test test_syntax_violation_callback_types ... ok
test test_url_from_file_path ... ok
test test_windows_unc_path ... ok
test test_socket_addrs ... ok
test result: ok. 61 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests url
running 66 tests
test url/src/lib.rs - (line 18) ... ok
test url/src/lib.rs - (line 26) ... ok
test url/src/lib.rs - (line 89) ... ok
test url/src/lib.rs - (line 57) ... ok
test url/src/lib.rs - (line 97) ... ok
test url/src/lib.rs - ParseOptions<'a>::syntax_violation_callback (line 222) ... ok
test url/src/lib.rs - Url::as_str (line 617) ... ok
test url/src/lib.rs - Url::authority (line 928) ... ok
test url/src/lib.rs - Url::cannot_be_a_base (line 964) ... ok
test url/src/lib.rs - Url::domain (line 1167) ... ok
test url/src/lib.rs - Url::from_file_path (line 2448) ... ok
test url/src/lib.rs - Url::fragment (line 1465) ... ok
test url/src/lib.rs - Url::has_authority (line 892) ... ok
test url/src/lib.rs - Url::has_host (line 1059) ... ok
test url/src/lib.rs - Url::host (line 1132) ... ok
test url/src/lib.rs - Url::host_str (line 1093) ... ok
test url/src/lib.rs - Url::into_string (line 640) ... ok
test url/src/lib.rs - Url::join (line 423) ... ok
test url/src/lib.rs - Url::make_relative (line 458) ... ok
test url/src/lib.rs - Url::options (line 590) ... ok
test url/src/lib.rs - Url::origin (line 812) ... ok
test url/src/lib.rs - Url::origin (line 795) ... ok
test url/src/lib.rs - Url::origin (line 829) ... ok
test url/src/lib.rs - Url::origin (line 846) ... ok
test url/src/lib.rs - Url::parse (line 323) ... ok
test url/src/lib.rs - Url::parse_with_params (line 351) ... ok
test url/src/lib.rs - Url::password (line 1021) ... ok
test url/src/lib.rs - Url::path (line 1314) ... ok
test url/src/lib.rs - Url::path_segments (line 1350) ... ok
test url/src/lib.rs - Url::port (line 1198) ... ok
test url/src/lib.rs - Url::query (line 1386) ... ok
test url/src/lib.rs - Url::port_or_known_default (line 1230) ... ok
test url/src/lib.rs - Url::query_pairs_mut (line 1607) ... ok
test url/src/lib.rs - Url::query_pairs (line 1425) ... ok
test url/src/lib.rs - Url::set_fragment (line 1499) ... ok
test url/src/lib.rs - Url::scheme (line 866) ... ok
test url/src/lib.rs - Url::set_host (line 1888) ... ok
test url/src/lib.rs - Url::set_host (line 1872) ... ok
test url/src/lib.rs - Url::set_host (line 1904) ... ok
test url/src/lib.rs - Url::set_host (line 1920) ... ok
test url/src/lib.rs - Url::set_ip_host (line 2078) ... ok
test url/src/lib.rs - Url::set_ip_host (line 2063) ... ok
test url/src/lib.rs - Url::set_password (line 2112) ... ok
test url/src/lib.rs - Url::set_path (line 1669) ... ok
test url/src/lib.rs - Url::set_port (line 1779) ... ok
test url/src/lib.rs - Url::set_port (line 1760) ... ok
test url/src/lib.rs - Url::set_port (line 1795) ... ok
test url/src/lib.rs - Url::set_query (line 1557) ... ok
test url/src/lib.rs - Url::set_scheme (line 2297) ... ok
test url/src/lib.rs - Url::set_scheme (line 2312) ... ok
test url/src/lib.rs - Url::set_scheme (line 2344) ... ok
test url/src/lib.rs - Url::set_scheme (line 2328) ... ok
test url/src/lib.rs - Url::set_scheme (line 2374) ... ok
test url/src/lib.rs - Url::set_scheme (line 2359) ... ok
test url/src/lib.rs - Url::set_username (line 2197) ... ok
test url/src/lib.rs - Url::set_username (line 2212) ... ok
test url/src/lib.rs - Url::socket_addrs (line 1263) - compile ... ok
test url/src/lib.rs - Url::socket_addrs (line 1270) ... ok
test url/src/lib.rs - Url::to_file_path (line 2608) ... ok
test url/src/lib.rs - Url::username (line 991) ... ok
test url/src/path_segments.rs - path_segments::PathSegmentsMut (line 20) ... ok
test url/src/path_segments.rs - path_segments::PathSegmentsMut<'a>::clear (line 80) ... ok
test url/src/path_segments.rs - path_segments::PathSegmentsMut<'a>::extend (line 183) ... ok
test url/src/path_segments.rs - path_segments::PathSegmentsMut<'a>::extend (line 203) ... ok
test url/src/slicing.rs - slicing::Position (line 44) ... ok
test url/src/path_segments.rs - path_segments::PathSegmentsMut<'a>::pop_if_empty (line 108) ... ok
test result: ok. 66 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.41s
nl -ba url/src/lib.rs | sed -n '300,365p'
Chunk ID: 265539
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 611
Output:
300 if let Some(ref mut index) = self.fragment_start {
301 *index += "/.".len() as u32;
302 }
303 }
304 (false, Some(marker_start)) => {
305 self.serialization
306 .drain(marker_start as usize..self.path_start as usize);
307 self.path_start = marker_start;
308 if let Some(ref mut index) = self.query_start {
309 *index -= "/.".len() as u32;
310 }
311 if let Some(ref mut index) = self.fragment_start {
312 *index -= "/.".len() as u32;
313 }
314 }
315 _ => {}
316 }
317 }
318
319 /// Parse an absolute URL from a string.
320 ///
321 /// # Examples
322 ///
323 /// ```rust
324 /// use url::Url;
325 /// # use url::ParseError;
326 ///
327 /// # fn run() -> Result<(), ParseError> {
328 /// let url = Url::parse("https://example.net")?;
329 /// # Ok(())
330 /// # }
331 /// # run().unwrap();
332 /// ```
333 ///
334 /// # Errors
335 ///
336 /// If the function can not parse an absolute URL from the given string,
337 /// a [`ParseError`] variant will be returned.
338 ///
339 /// [`ParseError`]: enum.ParseError.html
340 #[inline]
341 pub fn parse(input: &str) -> Result<Url, crate::ParseError> {
342 Url::options().parse(input)
343 }
344
345 /// Parse an absolute URL from a string and add params to its query string.
346 ///
347 /// Existing params are not removed.
348 ///
349 /// # Examples
350 ///
351 /// ```rust
352 /// use url::Url;
353 /// # use url::ParseError;
354 ///
355 /// # fn run() -> Result<(), ParseError> {
356 /// let url = Url::parse_with_params("https://example.net?dont=clobberme",
357 /// &[("lang", "rust"), ("browser", "servo")])?;
358 /// assert_eq!("https://example.net/?dont=clobberme&lang=rust&browser=servo", url.as_str());
359 /// # Ok(())
360 /// # }
361 /// # run().unwrap();
362 /// ```
363 ///
364 /// # Errors
365 ///
nl -ba url/src/parser.rs | sed -n '755,825p'
Chunk ID: 9cb6d2
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 880
Output:
755 != "//"
756 });
757 let scheme_end = base_url.scheme_end;
758 debug_assert!(base_url.byte_at(scheme_end) == b':');
759 self.serialization
760 .push_str(base_url.slice(..scheme_end + 1));
761 if let Some(after_prefix) = input.split_prefix("//") {
762 return self.after_double_slash(after_prefix, scheme_type, scheme_end);
763 }
764 return self.after_double_slash(remaining, scheme_type, scheme_end);
765 }
766 let path_start = base_url.path_start_without_marker();
767 self.serialization.push_str(base_url.slice(..path_start));
768 self.serialization.push('/');
769 let remaining = self.parse_path(
770 scheme_type,
771 &mut true,
772 path_start as usize,
773 input_after_first_char,
774 );
775 self.with_query_and_fragment(
776 scheme_type,
777 base_url.scheme_end,
778 base_url.username_end,
779 base_url.host_start,
780 base_url.host_end,
781 base_url.host,
782 base_url.port,
783 path_start,
784 remaining,
785 )
786 }
787 _ => {
788 let path_start = base_url.path_start_without_marker();
789 self.serialization.push_str(base_url.slice(..path_start));
790 self.serialization.push_str(base_url.path());
791 // FIXME spec says just "remove last entry", not the "pop" algorithm
792 self.pop_path(scheme_type, path_start as usize);
793 // A special url always has a path.
794 // A path always starts with '/'
795 if self.serialization.len() == path_start as usize
796 && (SchemeType::from(base_url.scheme()).is_special() || !input.is_empty())
797 {
798 self.serialization.push('/');
799 }
800 let remaining = match input.split_first() {
801 (Some('/'), remaining) => self.parse_path(
802 scheme_type,
803 &mut true,
804 path_start as usize,
805 remaining,
806 ),
807 _ => {
808 self.parse_path(scheme_type, &mut true, path_start as usize, input)
809 }
810 };
811 self.with_query_and_fragment(
812 scheme_type,
813 base_url.scheme_end,
814 base_url.username_end,
815 base_url.host_start,
816 base_url.host_end,
817 base_url.host,
818 base_url.port,
819 path_start,
820 remaining,
821 )
822 }
823 }
824 }
825
nl -ba url/src/parser.rs | sed -n '1360,1395p'
Chunk ID: 22ae8e
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 343
Output:
1360 let mut url = Url {
1361 serialization: self.serialization,
1362 scheme_end,
1363 username_end,
1364 host_start,
1365 host_end,
1366 host,
1367 port,
1368 path_start,
1369 query_start,
1370 fragment_start,
1371 };
1372 url.ensure_non_special_path_marker();
1373 Ok(url)
1374 }
1375
1376 /// Return (query_start, fragment_start)
1377 fn parse_query_and_fragment(
1378 &mut self,
1379 scheme_type: SchemeType,
1380 scheme_end: u32,
1381 mut input: Input<'_>,
1382 ) -> ParseResult<(Option<u32>, Option<u32>)> {
1383 let mut query_start = None;
1384 match input.next() {
1385 Some('#') => {}
1386 Some('?') => {
1387 query_start = Some(to_u32(self.serialization.len())?);
1388 self.serialization.push('?');
1389 let remaining = self.parse_query(scheme_type, scheme_end, input);
1390 if let Some(remaining) = remaining {
1391 input = remaining
1392 } else {
1393 return Ok((query_start, None));
1394 }
1395 }
nl -ba url/src/slicing.rs | sed -n '145,158p'
Chunk ID: ea5f3a
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 161
Output:
145 debug_assert!(self.byte_at(self.host_end) == b':');
146 self.host_end as usize + ":".len()
147 } else {
148 self.host_end as usize
149 }
150 }
151
152 Position::AfterPort => self.path_start_without_marker() as usize,
153
154 Position::BeforePath => self.path_start as usize,
155
156 Position::AfterPath => match (self.query_start, self.fragment_start) {
157 (Some(q), _) => q as usize,
158 (None, Some(f)) => f as usize,
nl -ba url/tests/unit.rs | sed -n '35,100p'
Chunk ID: 9e0100
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 722
Output:
35 }
36
37 #[test]
38 fn non_special_path_starting_with_double_slash_uses_marker() {
39 let url = Url::parse("foo:/.//example/path?query#fragment").unwrap();
40 assert_eq!(url.as_str(), "foo:/.//example/path?query#fragment");
41 assert!(!url.has_authority());
42 assert_eq!(url.host_str(), None);
43 assert_eq!(url.path(), "//example/path");
44 assert_eq!(url.query(), Some("query"));
45 assert_eq!(url.fragment(), Some("fragment"));
46 assert_eq!(&url[Position::AfterPort..Position::BeforePath], "/.");
47 assert_eq!(&url[Position::BeforePath..Position::AfterPath], "//example/path");
48
49 let reparsed = Url::parse(url.as_str()).unwrap();
50 assert_eq!(reparsed.as_str(), url.as_str());
51 assert!(!reparsed.has_authority());
52 assert_eq!(reparsed.host_str(), None);
53 assert_eq!(reparsed.path(), "//example/path");
54 }
55
56 #[test]
57 fn non_special_join_recomputes_double_slash_marker() {
58 let base = Url::parse("foo:/.//a/b?old#frag").unwrap();
59
60 let keeps_double_slash = base.join("c").unwrap();
61 assert_eq!(keeps_double_slash.as_str(), "foo:/.//a/c");
62 assert_eq!(keeps_double_slash.path(), "//a/c");
63 assert_eq!(
64 &keeps_double_slash[Position::AfterPort..Position::BeforePath],
65 "/."
66 );
67
68 let removes_marker = base.join("../../c").unwrap();
69 assert_eq!(removes_marker.as_str(), "foo:/c");
70 assert_eq!(removes_marker.path(), "/c");
71 assert_eq!(
72 &removes_marker[Position::AfterPort..Position::BeforePath],
73 ""
74 );
75
76 let query_only = base.join("?new").unwrap();
77 assert_eq!(query_only.as_str(), "foo:/.//a/b?new");
78 assert_eq!(query_only.path(), "//a/b");
79
80 let fragment_only = base.join("#new").unwrap();
81 assert_eq!(fragment_only.as_str(), "foo:/.//a/b?old#new");
82 assert_eq!(fragment_only.path(), "//a/b");
83 }
84
85 #[test]
86 fn marker_is_not_used_for_host_bearing_or_special_urls() {
87 let host_url = Url::parse("foo://host//path").unwrap();
88 assert!(host_url.has_authority());
89 assert_eq!(host_url.path(), "//path");
90 assert_eq!(&host_url[Position::AfterPort..Position::BeforePath], "");
91
92 let special = Url::parse("http://example.com//path").unwrap();
93 assert!(special.has_authority());
94 assert_eq!(special.path(), "//path");
95 assert_eq!(&special[Position::AfterPort..Position::BeforePath], "");
96 }
97
98 #[test]
99 fn test_strip_trailing_spaces_from_opaque_path() {
100 let mut url: Url = "data:space ?query".parse().unwrap();
nl -ba url/src/lib.rs | sed -n '250,320p'
Chunk ID: e49416
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 731
Output:
250 context: Context::UrlParser,
251 }
252 .parse_url(input)
253 }
254 }
255
256 impl Url {
257 fn has_no_authority_components(&self) -> bool {
258 let scheme_end = self.scheme_end + ":".len() as u32;
259 self.username_end == scheme_end
260 && self.host_start == scheme_end
261 && self.host_end == scheme_end
262 && self.host == HostInternal::None
263 && self.port.is_none()
264 }
265
266 pub(crate) fn path_marker_start(&self) -> Option<u32> {
267 if SchemeType::from(self.scheme()).is_special()
268 || !self.has_no_authority_components()
269 || self.path_start < "/.".len() as u32
270 {
271 return None;
272 }
273
274 let marker_start = self.path_start - "/.".len() as u32;
275 if self.slice(marker_start..self.path_start) == "/." && self.path().starts_with("//") {
276 Some(marker_start)
277 } else {
278 None
279 }
280 }
281
282 pub(crate) fn path_start_without_marker(&self) -> u32 {
283 self.path_marker_start().unwrap_or(self.path_start)
284 }
285
286 pub(crate) fn ensure_non_special_path_marker(&mut self) {
287 let marker_start = self.path_marker_start();
288 let needs_marker = !SchemeType::from(self.scheme()).is_special()
289 && self.has_no_authority_components()
290 && self.path().starts_with("//");
291
292 match (needs_marker, marker_start) {
293 (true, None) => {
294 self.serialization
295 .insert_str(self.path_start as usize, "/.");
296 self.path_start += "/.".len() as u32;
297 if let Some(ref mut index) = self.query_start {
298 *index += "/.".len() as u32;
299 }
300 if let Some(ref mut index) = self.fragment_start {
301 *index += "/.".len() as u32;
302 }
303 }
304 (false, Some(marker_start)) => {
305 self.serialization
306 .drain(marker_start as usize..self.path_start as usize);
307 self.path_start = marker_start;
308 if let Some(ref mut index) = self.query_start {
309 *index -= "/.".len() as u32;
310 }
311 if let Some(ref mut index) = self.fragment_start {
312 *index -= "/.".len() as u32;
313 }
314 }
315 _ => {}
316 }
317 }
318
319 /// Parse an absolute URL from a string.
320 ///
nl -ba url/src/lib.rs | sed -n '660,705p'
Chunk ID: 40b570
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 522
Output:
660 /// Methods of the `Url` struct assume a number of invariants.
661 /// This checks each of these invariants and panic if one is not met.
662 /// This is for testing rust-url itself.
663 #[doc(hidden)]
664 pub fn check_invariants(&self) -> Result<(), String> {
665 macro_rules! assert {
666 ($x: expr) => {
667 if !$x {
668 return Err(format!(
669 "!( {} ) for URL {:?}",
670 stringify!($x),
671 self.serialization
672 ));
673 }
674 };
675 }
676
677 macro_rules! assert_eq {
678 ($a: expr, $b: expr) => {
679 {
680 let a = $a;
681 let b = $b;
682 if a != b {
683 return Err(format!("{:?} != {:?} ({} != {}) for URL {:?}",
684 a, b, stringify!($a), stringify!($b),
685 self.serialization))
686 }
687 }
688 }
689 }
690
691 assert!(self.scheme_end >= 1);
692 assert!(self.byte_at(0).is_ascii_alphabetic());
693 assert!(self
694 .slice(1..self.scheme_end)
695 .chars()
696 .all(|c| matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9' | '+' | '-' | '.')));
697 assert_eq!(self.byte_at(self.scheme_end), b':');
698
699 if self.has_authority() {
700 // URL with authority
701 if self.username_end != self.serialization.len() as u32 {
702 match self.byte_at(self.username_end) {
703 b':' => {
704 assert!(self.host_start >= self.username_end + 2);
705 assert_eq!(self.byte_at(self.host_start - 1), b'@');
nl -ba url/src/lib.rs | sed -n '1640,1675p'
Chunk ID: 64f946
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 331
Output:
1640 query_start = start as usize;
1641 } else {
1642 query_start = self.serialization.len();
1643 self.query_start = Some(to_u32(query_start).unwrap());
1644 self.serialization.push('?');
1645 }
1646
1647 let query = UrlQuery {
1648 url: Some(self),
1649 fragment,
1650 };
1651 form_urlencoded::Serializer::for_suffix(query, query_start + "?".len())
1652 }
1653
1654 fn take_after_path(&mut self) -> String {
1655 match (self.query_start, self.fragment_start) {
1656 (Some(i), _) | (None, Some(i)) => {
1657 let after_path = self.slice(i..).to_owned();
1658 self.serialization.truncate(i as usize);
1659 after_path
1660 }
1661 (None, None) => String::new(),
1662 }
1663 }
1664
1665 /// Change this URL’s path.
1666 ///
1667 /// # Examples
1668 ///
1669 /// ```rust
1670 /// use url::Url;
1671 /// # use url::ParseError;
1672 ///
1673 /// # fn run() -> Result<(), ParseError> {
1674 /// let mut url = Url::parse("https://example.com")?;
1675 /// url.set_path("api/comments");
nl -ba url/src/path_segments.rs | sed -n '60,72p'
Chunk ID: 60f1b0
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 94
Output:
60 old_after_path_position,
61 after_path,
62 }
63 }
64
65 impl<'a> Drop for PathSegmentsMut<'a> {
66 fn drop(&mut self) {
67 self.url.ensure_non_special_path_marker();
68 self.url
69 .restore_after_path(self.old_after_path_position, &self.after_path)
70 }
71 }
72
nl -ba url/src/lib.rs | sed -n '1700,1738p'
Chunk ID: cc13fe
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 483
Output:
1700 pub fn set_path(&mut self, mut path: &str) {
1701 let after_path = self.take_after_path();
1702 let old_after_path_pos = to_u32(self.serialization.len()).unwrap();
1703 let cannot_be_a_base = self.cannot_be_a_base();
1704 let scheme_type = SchemeType::from(self.scheme());
1705 let path_start = self.path_start_without_marker();
1706 self.serialization.truncate(path_start as usize);
1707 self.path_start = path_start;
1708 self.mutate(|parser| {
1709 if cannot_be_a_base {
1710 if path.starts_with('/') {
1711 parser.serialization.push_str("%2F");
1712 path = &path[1..];
1713 }
1714 parser.parse_cannot_be_a_base_path(parser::Input::new(path));
1715 } else {
1716 let mut has_host = true; // FIXME
1717 parser.parse_path_start(scheme_type, &mut has_host, parser::Input::new(path));
1718 }
1719 });
1720 self.ensure_non_special_path_marker();
1721 self.restore_after_path(old_after_path_pos, &after_path);
1722 }
1723
1724 /// Return an object with methods to manipulate this URL’s path segments.
1725 ///
1726 /// Return `Err(())` if this URL is cannot-be-a-base.
1727 #[allow(clippy::result_unit_err)]
1728 pub fn path_segments_mut(&mut self) -> Result<PathSegmentsMut<'_>, ()> {
1729 if self.cannot_be_a_base() {
1730 Err(())
1731 } else {
1732 Ok(path_segments::new(self))
1733 }
1734 }
1735
1736 fn restore_after_path(&mut self, old_after_path_position: u32, after_path: &str) {
1737 let new_after_path_position = to_u32(self.serialization.len()).unwrap();
1738 let adjust = |index: &mut u32| {
No file changes, the agent left the workspace untouched.
============================= test session starts ============================== platform linux -- Python 3.11.2, pytest-8.3.3, pluggy-1.6.0 -- /opt/test-venv/bin/python3 cachedir: .pytest_cache rootdir: /tests collecting ... collected 4 items ../tests/test_outputs.py::test_url_roundtrip_suite_passes PASSED [ 25%] ../tests/test_outputs.py::test_existing_url_unit_tests_still_pass PASSED [ 50%] ../tests/test_outputs.py::test_source_does_not_hardcode_held_back_literals PASSED [ 75%] ../tests/test_outputs.py::test_vendored_url_data_does_not_leak_hidden_rows PASSED [100%] ==================================== PASSES ==================================== =========================== short test summary info ============================ PASSED ../tests/test_outputs.py::test_url_roundtrip_suite_passes PASSED ../tests/test_outputs.py::test_existing_url_unit_tests_still_pass PASSED ../tests/test_outputs.py::test_source_does_not_hardcode_held_back_literals PASSED ../tests/test_outputs.py::test_vendored_url_data_does_not_leak_hidden_rows ============================== 4 passed in 0.22s ===============================
Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_b22adfc7c57f4de9. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_b22adfc7c57f4de9 · verifier authoritative; classifier explanatory.