summaryrefslogtreecommitdiffstats
path: root/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/main.zig b/src/main.zig
new file mode 100644
index 0000000..6bb9777
--- /dev/null
+++ b/src/main.zig
@@ -0,0 +1,118 @@
+//! 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");
+}