diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-26 12:48:43 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-26 12:48:43 -0300 |
| commit | 87166a5299aa551517a86379a0c05eb2110b52b0 (patch) | |
| tree | 3e77e7dd89cca736a22a5f2219451aa57dd99068 /src/main.zig | |
| download | zig-87166a5299aa551517a86379a0c05eb2110b52b0.tar.gz | |
Initial importv0.1.0
Diffstat (limited to 'src/main.zig')
| -rw-r--r-- | src/main.zig | 118 |
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"); +} |