@@ -134,6 +134,7 @@ pub const ParseError = error{ UnexpectedCharacter, InvalidFormat, InvalidPort };
134134/// original `text`. Each component that is provided, will be non-`null`.
135135pub fn parseWithoutScheme (text : []const u8 ) ParseError ! Uri {
136136 var reader = SliceReader { .slice = text };
137+
137138 var uri = Uri {
138139 .scheme = "" ,
139140 .user = null ,
@@ -145,13 +146,14 @@ pub fn parseWithoutScheme(text: []const u8) ParseError!Uri {
145146 .fragment = null ,
146147 };
147148
148- if (reader .peekPrefix ("//" )) { // authority part
149+ if (reader .peekPrefix ("//" )) a : { // authority part
149150 std .debug .assert (reader .get ().? == '/' );
150151 std .debug .assert (reader .get ().? == '/' );
151152
152153 const authority = reader .readUntil (isAuthoritySeparator );
153- if (authority .len == 0 )
154- return error .InvalidFormat ;
154+ if (authority .len == 0 ) {
155+ if (reader .peekPrefix ("/" )) break :a else return error .InvalidFormat ;
156+ }
155157
156158 var start_of_host : usize = 0 ;
157159 if (std .mem .indexOf (u8 , authority , "@" )) | index | {
@@ -224,7 +226,6 @@ pub fn format(
224226 try writer .writeAll (":" );
225227 if (uri .host ) | host | {
226228 try writer .writeAll ("//" );
227-
228229 if (uri .user ) | user | {
229230 try writer .writeAll (user );
230231 if (uri .password ) | password | {
@@ -486,6 +487,23 @@ test "should fail gracefully" {
486487 try std .testing .expectEqual (@as (ParseError ! Uri , error .InvalidFormat ), parse ("foobar://" ));
487488}
488489
490+ test "file" {
491+ const parsed = try parse ("file:///" );
492+ try std .testing .expectEqualSlices (u8 , "file" , parsed .scheme );
493+ try std .testing .expectEqual (@as (? []const u8 , null ), parsed .host );
494+ try std .testing .expectEqualSlices (u8 , "/" , parsed .path );
495+
496+ const parsed2 = try parse ("file:///an/absolute/path/to/something" );
497+ try std .testing .expectEqualSlices (u8 , "file" , parsed2 .scheme );
498+ try std .testing .expectEqual (@as (? []const u8 , null ), parsed2 .host );
499+ try std .testing .expectEqualSlices (u8 , "/an/absolute/path/to/something" , parsed2 .path );
500+
501+ const parsed3 = try parse ("file://localhost/an/absolute/path/to/another/thing/" );
502+ try std .testing .expectEqualSlices (u8 , "file" , parsed3 .scheme );
503+ try std .testing .expectEqualSlices (u8 , "localhost" , parsed3 .host .? );
504+ try std .testing .expectEqualSlices (u8 , "/an/absolute/path/to/another/thing/" , parsed3 .path );
505+ }
506+
489507test "scheme" {
490508 try std .testing .expectEqualSlices (u8 , "http" , (try parse ("http:_" )).scheme );
491509 try std .testing .expectEqualSlices (u8 , "scheme-mee" , (try parse ("scheme-mee:_" )).scheme );
@@ -695,3 +713,20 @@ test "URI query escaping" {
695713 defer std .testing .allocator .free (formatted_uri );
696714 try std .testing .expectEqualStrings ("/?response-content-type=application%2Foctet-stream" , formatted_uri );
697715}
716+
717+ test "format" {
718+ const uri = Uri {
719+ .scheme = "file" ,
720+ .user = null ,
721+ .password = null ,
722+ .host = null ,
723+ .port = null ,
724+ .path = "/foo/bar/baz" ,
725+ .query = null ,
726+ .fragment = null ,
727+ };
728+ var buf = std .ArrayList (u8 ).init (std .testing .allocator );
729+ defer buf .deinit ();
730+ try uri .format ("+/" , .{}, buf .writer ());
731+ try std .testing .expectEqualSlices (u8 , "file:/foo/bar/baz" , buf .items );
732+ }
0 commit comments