use v6.d.PREVIEW; class Ultramarine::Model::DirScanner { has IO $.root is required; submethod BUILD(IO() :$!root!) {} class EndOfScan {} method scan(--> Supply) { my $ret = Supplier::Preserving.new; my sub inner-scan(IO() $path) { my @todo = $path; while @todo { my $next = @todo.pop; $ret.emit($next); next unless $next ~~ :d & :r & :x; $next.watch().tap({ inner-scan($^event.path) }); for $next.dir(:CWD($next.CWD)) -> $child { @todo.push($child); } CATCH { when X::IO::Dir { } } } } (start { inner-scan(IO::Path.new('.',:CWD($.root))); $ret.emit(EndOfScan); }).then(-> $p { $ret.quit($p.cause) if $p.status ~~ Broken }); CATCH { $ret.quit($_) }; return $ret.Supply; } }