//! A one-shot CLI over the library, mostly so `zig build run` can confirm that //! an instance answers. //! //! cepis 01001000 //! cepis --base-url http://localhost:8080 01001000 20040020 //! cepis --health const std = @import("std"); const cepis = @import("cepis"); const usage = \\usage: cepis [--base-url URL] [--health] [CEP ...] \\ \\ --base-url URL where the API lives (default https://cep.is) \\ --health query GET /health instead of looking anything up \\ --help show this message \\ ; pub fn main(init: std.process.Init) !u8 { const gpa = init.gpa; const io = init.io; const arena = init.arena.allocator(); var stdout_buffer: [4096]u8 = undefined; var stdout: std.Io.File.Writer = .init(.stdout(), io, &stdout_buffer); const out = &stdout.interface; defer out.flush() catch {}; const args = try init.minimal.args.toSlice(arena); var base_url: []const u8 = cepis.default_url; var want_health = false; var ceps: std.ArrayList([]const u8) = .empty; defer ceps.deinit(gpa); var i: usize = 1; while (i < args.len) : (i += 1) { const arg = args[i]; if (std.mem.eql(u8, arg, "--help") or std.mem.eql(u8, arg, "-h")) { try out.writeAll(usage); return 0; } else if (std.mem.eql(u8, arg, "--health")) { want_health = true; } else if (std.mem.eql(u8, arg, "--base-url")) { i += 1; if (i >= args.len) { try out.writeAll("--base-url needs a value\n"); return 2; } base_url = args[i]; } else { try ceps.append(gpa, arg); } } if (!want_health and ceps.items.len == 0) { try out.writeAll(usage); return 2; } var client: cepis.Client = try .init(gpa, io, .{ .base_url = base_url }); defer client.deinit(); var diag: cepis.Diagnostics = .{}; if (want_health) { var health = client.health(.{ .diagnostics = &diag }) catch |err| { try out.print("health failed: {t}: {s}\n", .{ err, diag.message() }); return 1; }; defer health.deinit(gpa); try out.print("{s} dne={s} ceps={d} geo={d} gerada_em={s}\n", .{ health.status, health.dne, health.ceps, health.geo, health.base_gerada_em, }); return 0; } if (ceps.items.len == 1) { var address = client.lookup(ceps.items[0], .{ .diagnostics = &diag }) catch |err| { try out.print("{s}: {t}: {s}\n", .{ ceps.items[0], err, diag.message() }); return 1; }; defer address.deinit(gpa); try printAddress(out, address); return 0; } const found = client.lookupMany(ceps.items, .{ .diagnostics = &diag }) catch |err| { try out.print("batch failed: {t}: {s}\n", .{ err, diag.message() }); return 1; }; defer cepis.freeAddresses(gpa, found); for (ceps.items, found) |requested, maybe_address| { if (maybe_address) |address| { try printAddress(out, address); } else { try out.print("{s}: not found\n", .{requested}); } } return 0; } fn printAddress(out: *std.Io.Writer, address: cepis.Address) !void { var buffer: [16]u8 = undefined; try out.print("{s} {s}, {s} — {s}/{s}", .{ address.formattedCep(&buffer), address.logradouro, address.bairro, address.localidade, address.uf, }); if (address.geo) |geo| { try out.print(" [{d:.6},{d:.6} ±{d}m {s}]", .{ geo.lat, geo.lon, geo.raio_m, geo.precisao }); } try out.writeAll("\n"); }