-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for zone identifiers #26
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR.
One other thing is that the types in this library generally keep track of whether they are normalized, but I'm not sure what it means for a zone ID to be normalized. It also doesn't specify whether it's case sensitive.
src/authority.rs
Outdated
@@ -773,7 +773,7 @@ pub enum Host<'host> { | |||
IPv4Address(Ipv4Addr), | |||
|
|||
/// An IPv6 address. This will always be encased in brackets (`'['` and `']'`). | |||
IPv6Address(Ipv6Addr), | |||
IPv6Address(Ipv6Addr, Cow<'host, str>), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the RFC says that a zone ID must be at least one character, I think it makes more sense to wrap this in an Option
.
src/authority.rs
Outdated
@@ -773,7 +773,7 @@ pub enum Host<'host> { | |||
IPv4Address(Ipv4Addr), | |||
|
|||
/// An IPv6 address. This will always be encased in brackets (`'['` and `']'`). | |||
IPv6Address(Ipv6Addr), | |||
IPv6Address(Ipv6Addr, Cow<'host, str>), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I generally prefer using strong types rather than strings (as you can see by the library having Port
, Username
, Password
, etc. types). I'd prefer if this was a new ZoneID
type.
src/authority.rs
Outdated
|
||
if !check_ipv6(ipv6) { | ||
if !check_ipv6(ipv6) || !check_zone(zone) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be better if this condition was done separately from check_ipv6
and a different error type was returned, something like InvalidIPv6ZoneIDCharacter
On Tue, Oct 11, 2022 at 10:47:29AM -0700, Scott Godwin wrote:
One other thing is that the types in this library generally keep track
of whether they are normalized, but I'm not sure what it means for a
zone ID to be normalized. It also doesn't specify whether it's case
sensitive.
The zone identifiers come quite directly from the operating system after
limiting to "unreserved", I don't see any mention of normalization, and
with only unreserved being allowed there can be no denormalized forms.
Since the RFC says that a zone ID must be at least one character, I
think it makes more sense to wrap this in an `Option`.
[...]
I generally prefer using strong types rather than strings (as you can
see by the library having `Port`, `Username`, `Password`, etc. types).
I'd prefer if this was a new `ZoneID` type.
Fine with me; then the ZoneID type would have being non-empty as a
validity constraint.
[...], something like `InvalidIPv6ZoneIDCharacter`
No problem.
Thanks for reviewing, fixes coming up.
|
Use dedicated type for ZoneID
Use dedicated error type for invalid zone characters
Use Option<non-empty-zone> instead of plain possibly-empty-zone
I think the update addresses all your points. I've isolated some creation and error logic into a private If you're happy with the changes I'd smush them into a single commit. |
formatter.write_char('[')?; | ||
address.fmt(formatter)?; | ||
if let Some(zone) = zone { | ||
formatter.write_char('%')?; | ||
formatter.write_str(zone.as_str())?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you implement Display
for zone ID and do zone.fmt(formatter)?
instead
} | ||
|
||
impl ZoneID<'_> { | ||
fn new<'a>(value: Option<&'a [u8]>) -> Result<Option<ZoneID<'a>>, HostError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following other types in this library, can you move this to a TryFrom<&[u8]>
implementation
/// characters. | ||
#[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub struct ZoneID<'zone> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit tedious, but can you impl all the traits other types do in this library? For example, just go through fragment and implement stuff like AsRef
, Deref
, PartialEq
with strings, etc.
Closes: #6
This is based on #25, please only consider the top commit. (But I'm using that PR in testing already; sadly there seems to be no way to tell GitHub that it's dependent on that PR). If #25 does get rejected, I can rebase it to get rid of those changes -- otherwise I think it's best to merge after it, and then things would be easy.
The implementation already follows https://datatracker.ietf.org/doc/draft-ietf-6man-rfc6874bis/ (the upcoming revision of RFC6874) in that it doesn't do any percent encoding of the percent sign.
As zone identifiers are necessarily non-empty, a URI with an IPv6 address without zone identifier is represented by an empty string as a zone identifier.
Testing
API
Given that the
enum Host
variants are exhaustive, this is an API breaking change -- and I don't see how it could be made non-breaking.