1 module served.io.nothrow_fs; 2 3 public import fs = std.file; 4 5 import std.experimental.logger; 6 import std.utf; 7 8 auto tryDirEntries(string path, fs.SpanMode mode, bool followSymlink = true) 9 { 10 try 11 { 12 return nothrowDirIterator(fs.dirEntries(path, mode, followSymlink)); 13 } 14 catch (fs.FileException) 15 { 16 return typeof(return).init; 17 } 18 } 19 20 auto tryDirEntries(string path, string pattern, fs.SpanMode mode, bool followSymlink = true) 21 { 22 try 23 { 24 return nothrowDirIterator(fs.dirEntries(path, pattern, mode, followSymlink)); 25 } 26 catch (fs.FileException) 27 { 28 return typeof(return).init; 29 } 30 } 31 32 private NothrowDirIterator!T nothrowDirIterator(T)(T range) 33 { 34 return NothrowDirIterator!T(range); 35 } 36 37 private struct NothrowDirIterator(T) 38 { 39 @safe: 40 T base; 41 bool crashed; 42 43 public: 44 @property bool empty() 45 { 46 try 47 { 48 return crashed || base.empty; 49 } 50 catch (fs.FileException) 51 { 52 return crashed = true; 53 } 54 catch (UTFException e) 55 { 56 (() @trusted => error("Got malformed UTF string in dirIterator, something has probably corrupted. ", e))(); 57 return crashed = true; 58 } 59 } 60 61 @property auto front() 62 { 63 try 64 { 65 return base.front; 66 } 67 catch (fs.FileException) 68 { 69 crashed = true; 70 } 71 catch (UTFException e) 72 { 73 (() @trusted => error("Got malformed UTF string in dirIterator, something has probably corrupted. ", e))(); 74 crashed = true; 75 } 76 return fs.DirEntry.init; 77 } 78 79 void popFront() 80 { 81 try 82 { 83 base.popFront(); 84 } 85 catch (fs.FileException) 86 { 87 crashed = true; 88 } 89 catch (UTFException e) 90 { 91 (() @trusted => error("Got malformed UTF string in dirIterator, something has probably corrupted. ", e))(); 92 crashed = true; 93 } 94 } 95 }