Directory interface - chung-leong/zigar GitHub Wiki

Interface implemented by objects representing directory in the virtual file system. It contains methods for obtaining the names of child items. Methods can be either synchronous or asynchronous, with the latter case limiting operations to worker threads.

Objects implementing the file interface are used in the following contexts:

Automatic conversion

A JavaScript Map will get automatically converted into a object with a directory interface. The key should be a string containing the name while the value should be an object containing the field type, which can be 'unknown', 'blockDevice', 'characterDevice', 'directory', 'file', 'socketDgram', or 'socketStream', and potentially ino, an item's inode number.

Example 1:

const std = @import("std");

pub fn scan(dir: std.fs.Dir) !void {
    var iter = dir.iterate();
    while (try iter.next()) |entry| {
        const entry_type = switch (entry.kind) {
            .file => "file",
            .directory => "dir",
            else => "unknown",
        };
        std.debug.print("{s} ({s})\n", .{ entry.name, entry_type });
    }
}
import { scan } from './dir-example-1.zig';

const map = new Map([
  [ 'harry-truman.txt', { type: 'file' } ],
  [ 'doris-day.txt', { type: 'file' } ],
  [ 'red-china.txt', { type: 'file' } ],
  [ 'johnnie-ray.txt', { type: 'file' } ],
  [ 'south-pacific.txt', { type: 'file' } ],
  [ 'walter-winchell.txt', { type: 'file' } ],
  [ 'joe-dimaggio.txt', { type: 'file' } ],
  [ 'wiki', { type: 'directory' } ],
]);
scan(map);
map.close();
harry-truman.txt (file)
doris-day.txt (file)
red-china.txt (file)
johnnie-ray.txt (file)
south-pacific.txt (file)
walter-winchell.txt (file)
joe-dimaggio.txt (file)
wiki (dir)

A close method gets attach to the original object during the conversion to std.fs.Dir. It allows you to close the file descriptor on the JavaScript side. Without the call to close() a descriptor would be left tangling, preventing the map from being garbage collected.

When std.fs.Dir.openFile gets called, the ['open'] listener will receive an object whose parent field points to the map.

const std = @import("std");

pub fn print(dir: std.fs.Dir, name: []const u8) !void {
    var file = try dir.openFile(name, .{});
    defer file.close();
    var write_buffer: [1024]u8 = undefined;
    var stdout_writer = std.fs.File.stdout().writer(&write_buffer);
    const stdout = &stdout_writer.interface;
    var read_buffer: [1024]u8 = undefined;
    while (true) {
        const len = try file.read(&read_buffer);
        if (len == 0) break;
        _ = try stdout.write(read_buffer[0..len]);
    }
    _ = try stdout.write("\n");
    try stdout.flush();
}
import { __zigar, print } from './dir-example-2.zig';

__zigar.on('open', ({ parent, path }) => parent?.get?.(path)?.content ?? false);

const map = new Map([
  [ 'harry-truman.txt', { type: 'file', content: 'The 33rd president of the United States' } ],
  [ 'doris-day.txt', { type: 'file', content: 'A shining star of the movie musicals of the 1950s' } ],
  [ 'red-china.txt', { type: 'file', content: 'Communist victory in China’s 1945-49 civil war led to the establishment of the People’s Republic of China' } ],
  [ 'johnnie-ray.txt', { type: 'file', content: 'The Elvis of the early 1950s' } ],
  [ 'south-pacific.txt', { type: 'file', content: 'Rodgers and Hammerstein musical' } ],
  [ 'walter-winchell.txt', { type: 'file', content: 'A journalist and radio host whose mix of news and gossip attracted the attention of Americans from the 1930s through the 1950s' } ],
  [ 'joe-dimaggio.txt', { type: 'file', content: 'Baseball star with the New York Yankees' } ],
  [ 'wiki', { type: 'directory' } ],
]);
print(map, 'harry-truman.txt');
print(map, 'joe-dimaggio.txt');
map.close();
The 33rd president of the United States
Baseball star with the New York Yankees

Methods

If the built-in support is unable to meet your needs, you can define a directory class of your own. It should have the following methods:

  • readdir(len)
    Get information about the next item in the directory. The return value is expected to be { name, type, ino }.
  • seek(index) Set the index of the next item to be read.
  • tell() Return the index of the next item.

Virtual file system | File interface