Interface struct ‣ Directory - chung-leong/zigar GitHub Wiki

The std.fs.Dir struct provides an interface to a directory in Zig. Objects implementing the directory interface can be passed to Zig functions accepting this struct as arguments. A JavaScript Map is can be used to represent a directory:

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)

The close() function attached to the map to release the file descriptor during the conversion process. You can also choose to close the directory on the Zig side with the help of @constCast():

    defer @constCast(&dir).close()

Opening a file

A listener for the 'open' event will receive the original object as parent when std.fs.dir.openFile() is used to open one of the files contained in the directory:

const std = @import("std");

pub fn print(dir: std.fs.Dir, name: []const u8) !void {
    var file = try dir.openFile(name, .{});
    defer file.close();
    const stdout = std.io.getStdOut();
    var buffer: [1024]u8 = undefined;
    while (true) {
        const len = try file.read(&buffer);
        if (len == 0) break;
        _ = try stdout.write(buffer[0..len]);
    }
    _ = try stdout.write("\n");
}
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

Note:

Calling std.fs.Dir.iterate() with a virtual directory will crash on Linux on certain platforms due the use of direct syscalls.


Interface structs | Directory interface