summaryrefslogtreecommitdiffstats
path: root/source/cepis/package.d
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-26 12:47:38 -0300
committerMurilo Ijanc <[email protected]>2026-07-26 12:47:38 -0300
commit794f28199a4dde9d18ec711864336c96c58bb422 (patch)
tree3985f1c033a9c62a264829cd354da9ce214e5db7 /source/cepis/package.d
downloadd-794f28199a4dde9d18ec711864336c96c58bb422.tar.gz
Initial importv0.1.0
Diffstat (limited to 'source/cepis/package.d')
-rw-r--r--source/cepis/package.d111
1 files changed, 111 insertions, 0 deletions
diff --git a/source/cepis/package.d b/source/cepis/package.d
new file mode 100644
index 0000000..073d377
--- /dev/null
+++ b/source/cepis/package.d
@@ -0,0 +1,111 @@
+/**
+ * D client for the public CEP API at $(LINK https://cep.is). Official Correios
+ * data (DNE), refreshed every two weeks.
+ *
+ * Quick use — for a script, the module-level functions are enough:
+ *
+ * ---
+ * import cepis;
+ *
+ * auto address = lookup("01001-000");
+ * writeln(address.localidade, " ", address.uf); // São Paulo SP
+ * ---
+ *
+ * In an application — build a $(D Client) once and reuse it:
+ *
+ * ---
+ * ClientConfig config;
+ * config.timeout = dur!"seconds"(5);
+ * config.totalTimeout = dur!"seconds"(15);
+ *
+ * auto client = Client(config);
+ * auto address = client.lookup("01001000");
+ * ---
+ *
+ * Pointing at a local instance (the API repo brings one up with `just up`):
+ *
+ * ---
+ * ClientConfig config;
+ * config.baseUrl = "http://localhost:8080";
+ * auto client = Client(config);
+ * ---
+ *
+ * Errors are explicit and split by decision — whether retrying helps or not:
+ *
+ * ---
+ * try
+ * render(lookup(cepFromForm));
+ * catch (CepNotFoundException)
+ * askForAnotherCep(); // the CEP does not exist
+ * catch (CepisException error)
+ * if (error.retriable) reschedule(); // network, server, rate limit
+ * ---
+ *
+ * Note on field names: the API surface is English, but the $(B data fields keep
+ * the API's own Portuguese names) ($(D logradouro), $(D bairro),
+ * $(D localidade)). What you read in the JSON is what you access on the value.
+ *
+ * The module-level functions share one default client per thread, built on
+ * first use. Anyone needing different settings should build their own
+ * $(D Client).
+ */
+module cepis;
+
+public import cepis.client;
+public import cepis.exception;
+public import cepis.model;
+
+import std.typecons : Nullable;
+
+@safe:
+
+/**
+ * Look up a CEP using the default configuration.
+ *
+ * Shorthand for `Client(ClientConfig.init).lookup(cep)`; see $(D Client.lookup).
+ */
+Address lookup(scope const(char)[] cep)
+{
+ return defaultClient().lookup(cep);
+}
+
+/**
+ * Look up many CEPs in one batch, using the default configuration.
+ *
+ * Shorthand for $(D Client.lookupMany) — read that one, especially the warning
+ * that batches carry no coordinate.
+ */
+Nullable!Address[] lookupMany(scope const(string)[] ceps)
+{
+ return defaultClient().lookupMany(ceps);
+}
+
+/**
+ * Query the API's health using the default configuration.
+ *
+ * Shorthand for $(D Client.health).
+ */
+Health health()
+{
+ return defaultClient().health();
+}
+
+private Client defaultClient()
+{
+ static Client instance;
+ static bool built;
+
+ if (!built)
+ {
+ instance = Client(ClientConfig.init);
+ built = true;
+ }
+ return instance;
+}
+
+@("the default client is built once and points at the public API")
+unittest
+{
+ assert(defaultClient().baseUrl == DEFAULT_URL);
+ assert(defaultClient().maxAttempts == 3);
+}