経験は何よりも饒舌

10年後に真価を発揮するかもしれないブログ 

deno/std/nodeのfs.DirentでisBlockDeviceの判定ができないのはRustに実装がされていないから...ではない

追記: Rustにis_block_deviceがあって、Denoにはなかった
github.com


fs.readdir(path, options, callback)optionswithFileTypes: trueを指定すると、fs.Direntが返ってくる。
fs.Direntdirent.isBlockDevice()を使った例が以下。

$ node
Welcome to Node.js v16.13.1.
Type ".help" for more information.
> const files = fs.readdirSync(".", {withFileTypes: true})
undefined
> files[0].isFile()
true
> files[0].isBlockDevice()
false

しかし、Deno(std/node)では使えない。

$ deno
Deno 1.25.4
exit using ctrl+d or close()
> import {readdirSync} from "https://deno.land/std@0.157.0/node/fs.ts"
undefined
> const files = readdirSync(".", {withFileTypes: true})
undefined
> files[0].isFile()
false
> files[0].isBlockDevice()
Uncaught Error: Not implemented: Deno does not yet support identification of block devices
    at notImplemented (https://deno.land/std@0.157.0/node/_utils.ts:23:9)
    at Dirent.isBlockDevice (https://deno.land/std@0.157.0/node/_fs/_fs_dirent.ts:8:5)
    at <anonymous>:2:10

deno_std/node/_fs/_fs_dirent.tsを見るとnotImplementedとされている。

export default class Dirent {
  constructor(private entry: Deno.DirEntry) {}

  isBlockDevice(): boolean {
    notImplemented("Deno does not yet support identification of block devices");
    return false;
  }
  ...

std/nodeのreaddirSyncは内部的にはDeno.readDirSyncが使われているのでDenoのコードを見にいくとそれっぽい箇所があった。
is_fileがあるから上記の例でfiles[0].isFile()が使えている。

  FsStat {
    is_file: metadata.is_file(),
    is_directory: metadata.is_dir(),
    is_symlink: metadata.file_type().is_symlink(),
...

metadataの参照先はRustなのでRustのコードを見にいくとそれっぽい箇所があった。

impl Metadata {
    #[must_use]
    #[stable(feature = "file_type", since = "1.1.0")]
    pub fn file_type(&self) -> FileType {
        FileType(self.0.file_type())
    }

    #[must_use]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn is_dir(&self) -> bool {
        self.file_type().is_dir()
    }

    #[must_use]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn is_file(&self) -> bool {
        self.file_type().is_file()
    }

    #[must_use]
    #[stable(feature = "is_symlink", since = "1.58.0")]
    pub fn is_symlink(&self) -> bool {
        self.file_type().is_symlink()
    }
...

ここにis_block_deviceを生やせば解決するはず...だけどメタ的な意味でRustわからん