66
77#include " nix/util/error.hh"
88#include " nix/util/canon-path.hh"
9+ #include " nix/util/split.hh"
10+ #include " nix/util/util.hh"
11+ #include " nix/util/variant-wrapper.hh"
912
1013namespace nix {
1114
@@ -342,8 +345,7 @@ ParsedURL fixGitURL(const std::string & url);
342345bool isValidSchemeName (std::string_view scheme);
343346
344347/* *
345- * Either a ParsedURL or a verbatim string, but the string must be a valid
346- * ParsedURL. This is necessary because in certain cases URI must be passed
348+ * Either a ParsedURL or a verbatim string. This is necessary because in certain cases URI must be passed
347349 * verbatim (e.g. in builtin fetchers), since those are specified by the user.
348350 * In those cases normalizations performed by the ParsedURL might be surprising
349351 * and undesirable, since Nix must be a universal client that has to work with
@@ -354,23 +356,23 @@ bool isValidSchemeName(std::string_view scheme);
354356 *
355357 * Though we perform parsing and validation for internal needs.
356358 */
357- struct ValidURL : private ParsedURL
359+ struct VerbatimURL
358360{
359- std::optional<std::string> encoded;
361+ using Raw = std::variant<std::string, ParsedURL>;
362+ Raw raw;
360363
361- ValidURL (std::string str)
362- : ParsedURL(parseURL(str, /* lenient=*/ false ))
363- , encoded(std::move(str))
364+ VerbatimURL (std::string_view s)
365+ : raw(std::string{s})
364366 {
365367 }
366368
367- ValidURL (std::string_view str )
368- : ValidURL (std::string{str} )
369+ VerbatimURL (std::string s )
370+ : raw (std::move(s) )
369371 {
370372 }
371373
372- ValidURL (ParsedURL parsed )
373- : ParsedURL{ std::move (parsed)}
374+ VerbatimURL (ParsedURL url )
375+ : raw( std::move(url))
374376 {
375377 }
376378
@@ -379,25 +381,35 @@ struct ValidURL : private ParsedURL
379381 */
380382 std::string to_string () const
381383 {
382- return encoded.or_else ([&]() -> std::optional<std::string> { return ParsedURL::to_string (); }).value ();
384+ return std::visit (
385+ overloaded{
386+ [](const std::string & str) { return str; }, [](const ParsedURL & url) { return url.to_string (); }},
387+ raw);
383388 }
384389
385- const ParsedURL & parsed () const &
390+ const ParsedURL parsed () const
386391 {
387- return *this ;
392+ return std::visit (
393+ overloaded{
394+ [](const std::string & str) { return parseURL (str); }, [](const ParsedURL & url) { return url; }},
395+ raw);
388396 }
389397
390398 std::string_view scheme () const &
391399 {
392- return ParsedURL::scheme;
393- }
394-
395- const auto & path () const &
396- {
397- return ParsedURL::path;
400+ return std::visit (
401+ overloaded{
402+ [](std::string_view str) {
403+ auto scheme = splitPrefixTo (str, ' :' );
404+ if (!scheme)
405+ throw BadURL (" URL '%s' doesn't have a scheme" , str);
406+ return *scheme;
407+ },
408+ [](const ParsedURL & url) -> std::string_view { return url.scheme ; }},
409+ raw);
398410 }
399411};
400412
401- std::ostream & operator <<(std::ostream & os, const ValidURL & url);
413+ std::ostream & operator <<(std::ostream & os, const VerbatimURL & url);
402414
403415} // namespace nix
0 commit comments