@@ -45,16 +45,16 @@ fn verifyFolder(directory_name: []const u8, comptime verifier: VerifierFunction)
4545 const stderr_file = std .io .getStdErr ();
4646 const stderr = stderr_file .writer ();
4747
48- var directory = try std .fs .cwd ().openDir (directory_name , .{ .no_follow = true });
48+ var directory = try std .fs .cwd ().openDir (directory_name , .{ .iterate = true , . no_follow = true });
4949 defer directory .close ();
50- var dirs = try std .fs .cwd ().openIterableDir (directory_name , .{ .no_follow = true });
50+ var dirs = try std .fs .cwd ().openDir (directory_name , .{ . iterate = true , .no_follow = true });
5151 defer dirs .close ();
5252
5353 var success = true ;
5454
5555 var iterator = dirs .iterate ();
5656 while (try iterator .next ()) | entry | {
57- if (entry .kind != .File )
57+ if (entry .kind != .file )
5858 continue ;
5959 if (std .mem .endsWith (u8 , entry .name , ".json" )) {
6060 var file = try directory .openFile (entry .name , .{ .mode = .read_only });
@@ -96,16 +96,30 @@ fn verifyTagJson(
9696 json_data : []const u8 ,
9797 errors : * std .ArrayList ([]const u8 ),
9898) ! void {
99- var options = std.json.ParseOptions {
100- .allocator = allocator ,
101- .duplicate_field_behavior = .Error ,
99+ const options = std.json.ParseOptions {};
100+
101+ const parse_result = try std .json .parseFromSlice (std .json .Value , allocator , json_data , options );
102+ const root = parse_result .value ;
103+ defer parse_result .deinit ();
104+
105+ if (root != .object ) {
106+ try errors .append ("Root JSON is not an object" );
107+ return ;
108+ }
109+
110+ const obj = root .object ;
111+
112+ const description_val = obj .get ("description" ) orelse {
113+ try errors .append ("Missing field: description" );
114+ return ;
102115 };
103- var stream = std .json .TokenStream .init (json_data );
104116
105- const tag = try std .json .parse (TagDescription , & stream , options );
106- defer std .json .parseFree (TagDescription , tag , options );
117+ if (description_val != .string ) {
118+ try errors .append ("Field 'description' is not a string" );
119+ return ;
120+ }
107121
108- if (tag . description .len == 0 )
122+ if (description_val . string .len == 0 )
109123 try errors .append ("description is empty!" );
110124
111125 try tag_collection .put (try string_arena .dupe (u8 , name ), {}); // file names ought to be unique
@@ -118,36 +132,81 @@ fn verifyPackageJson(
118132) ! void {
119133 _ = name ;
120134
121- var options = std.json.ParseOptions {
122- .allocator = allocator ,
123- .duplicate_field_behavior = .Error ,
124- };
125- var stream = std .json .TokenStream .init (json_data );
135+ const options = std.json.ParseOptions {};
136+
137+ const parse_result = try std .json .parseFromSlice (std .json .Value , allocator , json_data , options );
138+ const root = parse_result .value ;
139+ defer parse_result .deinit ();
140+
141+ if (root != .object ) {
142+ try errors .append ("Root JSON is not an object" );
143+ return ;
144+ }
126145
127- const pkg = try std .json .parse (PackageDescription , & stream , options );
128- defer std .json .parseFree (PackageDescription , pkg , options );
146+ const obj = root .object ;
129147
130- if (pkg .author .len == 0 )
148+ const author_val = obj .get ("author" ) orelse {
149+ try errors .append ("Missing field: author" );
150+ return ;
151+ };
152+ if (author_val != .string ) {
153+ try errors .append ("Field 'author' is not a string" );
154+ return ;
155+ }
156+ if (author_val .string .len == 0 )
131157 try errors .append ("author is empty!" );
132158
133- if (pkg .git .len == 0 )
159+ const git_val = obj .get ("git" ) orelse {
160+ try errors .append ("Missing field: git" );
161+ return ;
162+ };
163+ if (git_val != .string ) {
164+ try errors .append ("Field 'git' is not a string" );
165+ return ;
166+ }
167+ if (git_val .string .len == 0 )
134168 try errors .append ("git is empty!" );
135169
136- if (pkg .description .len == 0 )
170+ const description_val = obj .get ("description" ) orelse {
171+ try errors .append ("Missing field: description" );
172+ return ;
173+ };
174+ if (description_val != .string ) {
175+ try errors .append ("Field 'description' is not a string" );
176+ return ;
177+ }
178+ if (description_val .string .len == 0 )
137179 try errors .append ("description is empty!" );
138180
139- if (pkg .root_file ) | root | {
140- if (root .len == 0 ) {
141- try errors .append ("root_file is empty! Use 'null' if the root file is unrequired." );
142- } else if (! std .mem .startsWith (u8 , root , "/" )) {
143- try errors .append ("root_file must start with a '/'!" );
181+ if (obj .get ("root_file" )) | rf_val | {
182+ switch (rf_val ) {
183+ .null = > {}, // okay, keine Prüfung
184+ .string = > | root_file | {
185+ if (root_file .len == 0 ) {
186+ try errors .append ("root_file is empty! Use 'null' if unrequired." );
187+ } else if (! std .mem .startsWith (u8 , root_file , "/" )) {
188+ try errors .append ("root_file must start with '/'!" );
189+ }
190+ },
191+ else = > try errors .append ("root_file must be a string or null" ),
144192 }
145193 }
146194
147- for (pkg .tags ) | tag | {
148- const entry = tag_collection .get (tag );
149- if (entry == null ) {
150- try errors .append (try std .fmt .allocPrint (string_arena , "Tag '{s}' does not exist!" , .{tag }));
195+ if (obj .get ("tags" )) | tags_val | {
196+ switch (tags_val ) {
197+ .array = > | tags_array | {
198+ for (tags_array .items ) | tag_val | {
199+ switch (tag_val ) {
200+ .string = > | tag | {
201+ if (tag_collection .get (tag ) == null ) {
202+ try errors .append (try std .fmt .allocPrint (string_arena , "Tag '{s}' does not exist!" , .{tag }));
203+ }
204+ },
205+ else = > try errors .append ("All tags must be strings" ),
206+ }
207+ }
208+ },
209+ else = > try errors .append ("tags must be an array" ),
151210 }
152211 }
153212}
0 commit comments