Luigit
repositories / termux-janitor

termux-janitor

Interactive cleanup assistant for Termux: transparent, safe, confirmed disk reclamation.

owned by admin

tools/janitor/query.zig

Raw
const std = @import("std");
const model_types = @import("model.zig");

pub fn queryLimit(
    model: *const model_types.Model,
    id: []const u8,
    json: bool,
    writer: *std.Io.Writer,
) !void {
    for (model.limits) |limit| {
        if (!std.mem.eql(u8, limit.id, id)) continue;
        if (json) {
            try writer.print("{f}\n", .{std.json.fmt(limit, .{})});
        } else {
            try writer.print("{s}: {s}\ncategory: {s}\nvalue: ", .{
                limit.id,
                limit.label,
                @tagName(limit.category),
            });
            try writeLimitValue(limit.value, writer);
            try writer.writeByte('\n');
        }
        return;
    }
    return error.LimitNotFound;
}

pub fn writeLimitValue(value: model_types.LimitValue, writer: *std.Io.Writer) !void {
    switch (value) {
        .scalar => |scalar| try writer.print("{d} {s}", .{
            scalar.value,
            @tagName(scalar.unit),
        }),
        .dimensions => |dimensions| try writer.print("{d}x{d}", .{
            dimensions.columns,
            dimensions.rows,
        }),
        .alternative => |alternative| try writer.print("{d} items or {d} milliseconds", .{
            alternative.items,
            alternative.milliseconds,
        }),
    }
}

pub fn queryAndroidPackage(
    model: *const model_types.Model,
    key: []const u8,
    json: bool,
    writer: *std.Io.Writer,
) !void {
    for (model.android_packages) |package| {
        const matches = std.mem.eql(u8, package.id, key) or
            std.mem.eql(u8, package.identifier, key);
        if (!matches) continue;
        if (json) {
            try writer.print("{f}\n", .{std.json.fmt(package, .{})});
        } else {
            try writer.print("{s}: {s}\nidentifier: {s}\nrole: {s}\nrevision: {d}\n", .{
                package.id,
                package.identifier,
                package.identifier,
                @tagName(package.role),
                package.revision,
            });
        }
        return;
    }
    return error.AndroidPackageNotFound;
}

pub fn queryThreshold(
    model: *const model_types.Model,
    key: []const u8,
    json: bool,
    writer: *std.Io.Writer,
) !void {
    for (model.thresholds) |threshold| {
        if (!std.mem.eql(u8, threshold.id, key) and !std.mem.eql(u8, threshold.key, key)) continue;
        if (json) {
            try writer.print("{f}\n", .{std.json.fmt(threshold, .{})});
        } else {
            try writer.print("{s}: {d} {s}\nrequirement: {s}@{d}\n", .{
                threshold.key,
                threshold.value,
                @tagName(threshold.unit),
                threshold.requirement.id,
                threshold.requirement.revision,
            });
        }
        return;
    }
    return error.ThresholdNotFound;
}

pub fn queryClassification(
    model: *const model_types.Model,
    key: []const u8,
    json: bool,
    writer: *std.Io.Writer,
) !void {
    const set = if (std.mem.eql(u8, key, "source_basenames"))
        model.classification.source_basenames
    else if (std.mem.eql(u8, key, "source_suffixes"))
        model.classification.source_suffixes
    else if (std.mem.eql(u8, key, "document_roots"))
        model.classification.document_roots
    else
        return error.ClassificationRuleNotFound;
    if (json) {
        try writer.print("{f}\n", .{std.json.fmt(set, .{})});
        return;
    }
    try writer.print("{s}: {d} values\nrequirement: {s}@{d}\n", .{
        key,
        set.values.len,
        set.requirement.id,
        set.requirement.revision,
    });
    for (set.values) |value| try writer.print("- {s}\n", .{value});
}

pub fn queryCliOption(
    model: *const model_types.Model,
    key: []const u8,
    json: bool,
    writer: *std.Io.Writer,
) !void {
    for (model.cli.options) |option| {
        const matches = std.mem.eql(u8, option.id, key) or
            std.mem.eql(u8, option.spelling, key);
        if (!matches) continue;
        if (json) {
            try writer.print("{f}\n", .{std.json.fmt(option, .{})});
        } else {
            try writer.print("{s}: {s}\n{s}\nargument: {s}\n", .{
                option.id,
                option.spelling,
                option.summary,
                @tagName(option.argument),
            });
        }
        return;
    }
    return error.CliOptionNotFound;
}