Add RelativeUri enum for types of relative links#2078
Conversation
thomas-zahner
left a comment
There was a problem hiding this comment.
Thank you for the PR! Looks pretty great 🚀
Co-authored-by: Thomas Zahner <thomas.zahner@protonmail.ch>
katrinafyi
left a comment
There was a problem hiding this comment.
Thanks for the review!
katrinafyi
left a comment
There was a problem hiding this comment.
I think I've replied to all of the comments so far :)
|
I’d like to suggest a refactor for By introducing a pub enum Link<'a> {
Absolute(Uri),
Relative(RelativeUri<'a>),
}
impl<'a> Link<'a> {
pub fn parse(text: &'a str) -> Result<Self, ErrorKind> {
let text = text.trim_ascii_start();
match Uri::try_from(text) {
Ok(uri) => Ok(Self::Absolute(uri)),
Err(ErrorKind::ParseUrl(ParseError::RelativeUrlWithoutBase, _)) => {
let rel = if text.starts_with("//") {
RelativeUri::Scheme(text)
} else if text.starts_with('/') {
RelativeUri::Root(text)
} else {
RelativeUri::Local(text)
};
Ok(Self::Relative(rel))
}
Err(e) => Err(e),
}
}
pub fn resolve_to(self, base: &BaseInfo) -> Result<Url, ErrorKind> {
match self {
Self::Absolute(uri) => Ok(uri.url),
Self::Relative(rel) => base.resolve_relative_link(&rel),
}
}
}Not too happy with the term Does this make sense? Sorry, not too deep into that topic, so there's a high chance I'm missing important context. |
|
Parse don't validate (PDV) is about encoding properties that have been checked into the type itself and avoiding overly general types like String. The refactor you suggested doesn't increase PDV, because it's the same quantity of information just in different names (but if you do want different names, we can do that). In fact, both my current code and your suggestion fall afoul of "names are not type safety" because we've just given a name to &str without constraining what's inside the string. As you noted, the slicing If we were to increase PDV, that would look like replacing the &str inside SchemeRel with a specific type that knows it always starts with //. Something like This could be done using something like refinement types - specifically, a StartsWith predicate. Or, if that's too heavy, I can write a basic type myself. Or, we just use unwrap_or :) |
|
You're right. Let's dismiss that idea. So the only open point from my side would be #2078 (comment). |
i also use it in the Root case for consistency
Co-authored-by: Thomas Zahner <thomas.zahner@protonmail.ch>
everyone should use RelativeUri::new if they want to discriminate on relative link types.
This adds an enum:
This lets us cleans up some logic that depended on the relative link kind, and it lets us use a more explicit match in BaseInfo.