@@ -28,6 +28,7 @@ import std.file;
2828import std.path ;
2929import std.string ;
3030import std.typecons : Flag, No;
31+ import taggedalgebraic.taggedunion;
3132
3233
3334version (Posix ){
@@ -331,6 +332,78 @@ FileInfo getFileInfo(string path)
331332 return ret[0 ];
332333}
333334
335+ /* * Returns file information about multiple files at once.
336+
337+ This version of `getFileInfo` is more efficient than many individual calls
338+ to the singular version.
339+ */
340+ FileInfoResult[] getFileInfo (const (NativePath)[] paths)
341+ nothrow {
342+ import vibe.core.channel : Channel, ChannelConfig, ChannelPriority, createChannel;
343+ import vibe.core.core : runTask, runWorkerTask;
344+
345+ if (! paths.length) return null ;
346+
347+ ChannelConfig cc;
348+ cc.priority = ChannelPriority.overhead;
349+
350+ Channel! NativePath inch;
351+ Channel! FileInfoResult outch;
352+
353+ try {
354+ inch = createChannel! NativePath(cc);
355+ outch = createChannel! FileInfoResult(cc);
356+ } catch (Exception e) assert (false , e.msg);
357+
358+ static void getInfos (Channel! NativePath inch, Channel! FileInfoResult outch) nothrow {
359+ NativePath p;
360+ while (inch.tryConsumeOne(p)) {
361+ FileInfoResult fi;
362+ if (! existsFile(p)) fi = FileInfoResult.missing;
363+ else {
364+ try {
365+ auto ent = DirEntry (p.toString);
366+ fi = FileInfoResult.info(makeFileInfo(ent));
367+ } catch (Exception e) {
368+ fi = FileInfoResult.error(e.msg.length ? e.msg : " Failed to get file information" );
369+ }
370+ }
371+ try outch.put(fi);
372+ catch (Exception e) assert (false , e.msg);
373+ }
374+ outch.close();
375+ }
376+
377+ try runWorkerTask (&getInfos, inch, outch);
378+ catch (Exception e) assert (false , e.msg);
379+
380+ runTask(() nothrow {
381+ foreach (p; paths) {
382+ try inch.put(p);
383+ catch (Exception e) assert (false , e.msg);
384+ }
385+ inch.close();
386+ });
387+
388+ auto ret = new FileInfoResult[](paths.length);
389+ size_t i = 0 ;
390+ foreach (ref fi; ret) {
391+ if (! outch.tryConsumeOne(fi))
392+ assert (false );
393+ }
394+ assert (outch.empty);
395+
396+ return ret;
397+ }
398+
399+ struct FileInfoResultFields {
400+ Void missing;
401+ string error;
402+ FileInfo info;
403+ }
404+ alias FileInfoResult = TaggedUnion! FileInfoResultFields;
405+
406+
334407/**
335408 Creates a new directory.
336409*/
0 commit comments