-
-
Notifications
You must be signed in to change notification settings - Fork 339
Description
When writing a library that needs to abstract over URLs I've ran into the problem that the Rust ecosystem has two incompatible URL types: http::Uri
and url::Url
.
Unfortunately the API choices both crates have made make them incompatible:
-
Url
has.as_str()
, because it stores the full URL as a string and uses integer offsets to mark start/end of scheme, authority, etc. -
Uri
exposesScheme
,Authority
andPathAndQuery
as separate objects, which don't have a lifetime attached.
To be honest, Servo's implementation seems better to me. It simply stores the entire URL with just one heap allocation, instead of up to three. It can use 32-bit offsets instead of usize
length + vtable + atomicptr for each part (Bytes
). And it's very convenient to have as_str()
.
I think Uri
could switch to that design if it added lifetimes on Scheme<'_>
/Authority<'_>
/PathAndQuery<'_>
, so these could work similarly to Cow<'static, str>
and either own their string or borrow from their parent Uri
's single allocation.
With a bit of unsafety, I think this might even be done without breaking API changes by hiding the lifetime. Since Uri
exposes only shared/immutable references to these objects, they won't outlive their owning Uri
anyway.
Once Uri
has .as_str()
, Servo's URL could switch to being just a wrapper around the Uri
, with Deref
and From
operations for Uri
at zero cost, nicely unifying the types.
What do you think?