Skip to content

Commit a3df365

Browse files
littledivyAaronO
andauthored
feat(url): add quirks::internal_components (#788)
Co-authored-by: Aaron O'Mullan <[email protected]>
1 parent 868719d commit a3df365

File tree

4 files changed

+74
-1
lines changed

4 files changed

+74
-1
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
uses: actions-rs/cargo@v1
5050
with:
5151
command: test
52-
args: --features "url/serde"
52+
args: --features "url/serde,url/expose_internals"
5353
# The #[debugger_visualizer] attribute is currently gated behind an unstable feature flag.
5454
# In order to test the visualizers for the url crate, they have to be tested on a nightly build.
5555
- name: Run debugger_visualizer tests

url/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ default = ["idna"]
3838
# UNSTABLE FEATURES (requires Rust nightly)
3939
# Enable to use the #[debugger_visualizer] attribute.
4040
debugger_visualizer = []
41+
# Expose internal offsets of the URL.
42+
expose_internals = []
4143

4244
[[bench]]
4345
name = "parse_url"

url/src/quirks.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,49 @@
1414
use crate::parser::{default_port, Context, Input, Parser, SchemeType};
1515
use crate::{Host, ParseError, Position, Url};
1616

17+
/// Internal components / offsets of a URL.
18+
///
19+
/// https://user@pass:example.com:1234/foo/bar?baz#quux
20+
/// | | | | ^^^^| | |
21+
/// | | | | | | | `----- fragment_start
22+
/// | | | | | | `--------- query_start
23+
/// | | | | | `----------------- path_start
24+
/// | | | | `--------------------- port
25+
/// | | | `----------------------- host_end
26+
/// | | `---------------------------------- host_start
27+
/// | `--------------------------------------- username_end
28+
/// `---------------------------------------------- scheme_end
29+
#[derive(Copy, Clone)]
30+
#[cfg(feature = "expose_internals")]
31+
pub struct InternalComponents {
32+
pub scheme_end: u32,
33+
pub username_end: u32,
34+
pub host_start: u32,
35+
pub host_end: u32,
36+
pub port: Option<u16>,
37+
pub path_start: u32,
38+
pub query_start: Option<u32>,
39+
pub fragment_start: Option<u32>,
40+
}
41+
42+
/// Internal component / parsed offsets of the URL.
43+
///
44+
/// This can be useful for implementing efficient serialization
45+
/// for the URL.
46+
#[cfg(feature = "expose_internals")]
47+
pub fn internal_components(url: &Url) -> InternalComponents {
48+
InternalComponents {
49+
scheme_end: url.scheme_end,
50+
username_end: url.username_end,
51+
host_start: url.host_start,
52+
host_end: url.host_end,
53+
port: url.port,
54+
path_start: url.path_start,
55+
query_start: url.query_start,
56+
fragment_start: url.fragment_start,
57+
}
58+
}
59+
1760
/// https://url.spec.whatwg.org/#dom-url-domaintoascii
1861
pub fn domain_to_ascii(domain: &str) -> String {
1962
match Host::parse(domain) {

url/tests/unit.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,34 @@ fn test_domain_encoding_quirks() {
731731
}
732732
}
733733

734+
#[cfg(feature = "expose_internals")]
735+
#[test]
736+
fn test_expose_internals() {
737+
use url::quirks::internal_components;
738+
use url::quirks::InternalComponents;
739+
740+
let url = Url::parse("https://example.com/path/file.ext?key=val&key2=val2#fragment").unwrap();
741+
let InternalComponents {
742+
scheme_end,
743+
username_end,
744+
host_start,
745+
host_end,
746+
port,
747+
path_start,
748+
query_start,
749+
fragment_start,
750+
} = internal_components(&url);
751+
752+
assert_eq!(scheme_end, 5);
753+
assert_eq!(username_end, 8);
754+
assert_eq!(host_start, 8);
755+
assert_eq!(host_end, 19);
756+
assert_eq!(port, None);
757+
assert_eq!(path_start, 19);
758+
assert_eq!(query_start, Some(33));
759+
assert_eq!(fragment_start, Some(51));
760+
}
761+
734762
#[test]
735763
fn test_windows_unc_path() {
736764
if !cfg!(windows) {

0 commit comments

Comments
 (0)