import Dirent from "./_fs_dirent.ts";
export default class Dir { private dirPath: string | Uint8Array; private files: Dirent[] = []; private filesReadComplete = false;
constructor(path: string | Uint8Array) { this.dirPath = path; }
get path(): string { if (this.dirPath instanceof Uint8Array) { return new TextDecoder().decode(this.dirPath); } return this.dirPath; }
read(callback?: Function): Promise<Dirent | null> { return new Promise(async (resolve, reject) => { try { if (this.initializationOfDirectoryFilesIsRequired()) { const denoFiles: Deno.DirEntry[] = []; for await (const dirEntry of Deno.readdir(this.path)) { denoFiles.push(dirEntry); } this.files = denoFiles.map((file) => new Dirent(file)); } const nextFile = this.files.pop(); if (nextFile) { resolve(nextFile); this.filesReadComplete = this.files.length === 0; } else { this.filesReadComplete = true; resolve(null); } if (callback) { callback(null, !nextFile ? null : nextFile); } } catch (err) { if (callback) { callback(err, null); } reject(err); } }); }
readSync(): Dirent | null { if (this.initializationOfDirectoryFilesIsRequired()) { this.files.push( ...[...Deno.readdirSync(this.path)].map((file) => new Dirent(file)) ); } const dirent: Dirent | undefined = this.files.pop(); this.filesReadComplete = this.files.length === 0;
return !dirent ? null : dirent; }
private initializationOfDirectoryFilesIsRequired(): boolean { return this.files.length === 0 && !this.filesReadComplete; }
close(callback?: Function): Promise<void> { return new Promise((resolve, reject) => { try { if (callback) { callback(null); } resolve(); } catch (err) { if (callback) { callback(err); } reject(err); } }); }
closeSync(): void { }
async *[Symbol.asyncIterator](): AsyncIterableIterator<Dirent> { try { while (true) { const dirent: Dirent | null = await this.read(); if (dirent === null) { break; } yield dirent; } } finally { await this.close(); } }}