summaryrefslogtreecommitdiffstats
path: root/include/cepis/models.hpp
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-27 20:33:51 -0300
committerMurilo Ijanc <[email protected]>2026-07-27 20:33:51 -0300
commit2fb251996798798af38903fe535b8d147084a50a (patch)
tree9bcbb6ead9c7c4c1910495186707dc0f8859169d /include/cepis/models.hpp
parentb71faa6e95a0736f1ff171e006b171467b65db90 (diff)
downloadcpp-492ee0a03b6f23c3459cd32694cb1ed6bffdf014.tar.gz
Expose the municipality behind a not-found CEPHEADv0.2.0main
A CEP that fails a lookup is rarely random: it is usually someone who knows the city and guessed the number, and the classic guess is the -000 that 957 municipalities never received. The API now names, on the 404 itself, the municipality that CEP would have belonged to, so a caller can say "not found — did you mean somewhere in Areal/RJ?" instead of just "not found". CepNotFound carries it as an optional Faixa. It stays an error: the block is context, not an address, and the range it describes is sparse, which is why it reports a count alongside the first and last CEP that actually exist there rather than the bounds the Correios publish. Parsing it is best-effort on purpose — a missing, empty or malformed block leaves the optional empty, since a 404 is already the answer and reading the hint attached to it must never cost the diagnosis.
Diffstat (limited to 'include/cepis/models.hpp')
-rw-r--r--include/cepis/models.hpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/include/cepis/models.hpp b/include/cepis/models.hpp
index faa2dde..6252001 100644
--- a/include/cepis/models.hpp
+++ b/include/cepis/models.hpp
@@ -96,6 +96,45 @@ struct Address {
static Address from_json(const Json& data);
};
+/// The municipality a CEP that does **not** exist would have belonged to.
+///
+/// It arrives on a `404`, attached to `CepNotFound`. It is context for an
+/// error, never an address: the CEP still does not exist, and nothing in this
+/// block makes it deliverable. Treat it as a hint for the message you show —
+/// "did you mean somewhere in Areal/RJ?" — not as a result.
+///
+/// It exists because a CEP that fails is rarely random. It is usually someone
+/// who knows the city and guessed the number, and the classic guess is the
+/// `-000` that 957 municipalities never received.
+///
+/// `cep_ini` and `cep_fim` are the smallest and the largest CEP that
+/// **actually exist** in that municipality — not the bounds the Correios
+/// publish. For Areal the DNE's own start is `25845000`, which is precisely
+/// the CEP that just failed; `cep_ini` is `25845001`.
+///
+/// The range is also **sparse**: Areal's 118 CEPs are scattered across the
+/// ~4,900 numbers between `25845001` and `25849899`. That is what `ceps` is
+/// for. The pair is a span, not a list — walking from `cep_ini` to `cep_fim`
+/// produces thousands of CEPs that do not exist either.
+struct Faixa {
+ std::string localidade;
+ std::string uf;
+ std::string estado;
+ std::string regiao;
+ std::string ibge;
+ std::string cep_ini;
+ std::string cep_fim;
+ std::int64_t ceps = 0;
+
+ /// Reads the API's `faixa` block, or `std::nullopt` when it cannot be read.
+ ///
+ /// Anything unexpected — a missing block, a non-object, an empty one, a
+ /// municipality without a name — yields `std::nullopt` rather than an
+ /// error. The 404 is already the answer; failing to read the hint attached
+ /// to it must not turn a clean not-found into a parse failure.
+ static std::optional<Faixa> from_json(const Json& data);
+};
+
/// The response of `GET /health`.
///
/// Good for two things: checking that the API answers, and knowing **which