@@ -134,6 +134,7 @@ pub const ParseError = error{ UnexpectedCharacter, InvalidFormat, InvalidPort };
134
134
/// original `text`. Each component that is provided, will be non-`null`.
135
135
pub fn parseWithoutScheme (text : []const u8 ) ParseError ! Uri {
136
136
var reader = SliceReader { .slice = text };
137
+
137
138
var uri = Uri {
138
139
.scheme = "" ,
139
140
.user = null ,
@@ -145,13 +146,14 @@ pub fn parseWithoutScheme(text: []const u8) ParseError!Uri {
145
146
.fragment = null ,
146
147
};
147
148
148
- if (reader .peekPrefix ("//" )) { // authority part
149
+ if (reader .peekPrefix ("//" )) a : { // authority part
149
150
std .debug .assert (reader .get ().? == '/' );
150
151
std .debug .assert (reader .get ().? == '/' );
151
152
152
- const authority = reader .readUntil (isAuthoritySeparator );
153
- if (authority .len == 0 )
154
- return error .InvalidFormat ;
153
+ var authority = reader .readUntil (isAuthoritySeparator );
154
+ if (authority .len == 0 ) {
155
+ if (reader .peekPrefix ("/" )) break :a else return error .InvalidFormat ;
156
+ }
155
157
156
158
var start_of_host : usize = 0 ;
157
159
if (std .mem .indexOf (u8 , authority , "@" )) | index | {
@@ -223,7 +225,6 @@ pub fn format(
223
225
try writer .writeAll (":" );
224
226
if (uri .host ) | host | {
225
227
try writer .writeAll ("//" );
226
-
227
228
if (uri .user ) | user | {
228
229
try writer .writeAll (user );
229
230
if (uri .password ) | password | {
@@ -473,6 +474,23 @@ test "should fail gracefully" {
473
474
try std .testing .expectEqual (@as (ParseError ! Uri , error .InvalidFormat ), parse ("foobar://" ));
474
475
}
475
476
477
+ test "file" {
478
+ const parsed = try parse ("file:///" );
479
+ try std .testing .expectEqualSlices (u8 , "file" , parsed .scheme );
480
+ try std .testing .expectEqual (@as (? []const u8 , null ), parsed .host );
481
+ try std .testing .expectEqualSlices (u8 , "/" , parsed .path );
482
+
483
+ const parsed2 = try parse ("file:///an/absolute/path/to/something" );
484
+ try std .testing .expectEqualSlices (u8 , "file" , parsed2 .scheme );
485
+ try std .testing .expectEqual (@as (? []const u8 , null ), parsed2 .host );
486
+ try std .testing .expectEqualSlices (u8 , "/an/absolute/path/to/something" , parsed2 .path );
487
+
488
+ const parsed3 = try parse ("file://localhost/an/absolute/path/to/another/thing/" );
489
+ try std .testing .expectEqualSlices (u8 , "file" , parsed3 .scheme );
490
+ try std .testing .expectEqualSlices (u8 , "localhost" , parsed3 .host .? );
491
+ try std .testing .expectEqualSlices (u8 , "/an/absolute/path/to/another/thing/" , parsed3 .path );
492
+ }
493
+
476
494
test "scheme" {
477
495
try std .testing .expectEqualSlices (u8 , "http" , (try parse ("http:_" )).scheme );
478
496
try std .testing .expectEqualSlices (u8 , "scheme-mee" , (try parse ("scheme-mee:_" )).scheme );
@@ -682,3 +700,20 @@ test "URI query escaping" {
682
700
defer std .testing .allocator .free (formatted_uri );
683
701
try std .testing .expectEqualStrings ("/?response-content-type=application%2Foctet-stream" , formatted_uri );
684
702
}
703
+
704
+ test "format" {
705
+ const uri = Uri {
706
+ .scheme = "file" ,
707
+ .user = null ,
708
+ .password = null ,
709
+ .host = null ,
710
+ .port = null ,
711
+ .path = "/foo/bar/baz" ,
712
+ .query = null ,
713
+ .fragment = null ,
714
+ };
715
+ var buf = std .ArrayList (u8 ).init (std .testing .allocator );
716
+ defer buf .deinit ();
717
+ try uri .format ("+/" , .{}, buf .writer ());
718
+ try std .testing .expectEqualSlices (u8 , "file:/foo/bar/baz" , buf .items );
719
+ }
0 commit comments