diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-27 20:33:25 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-27 20:33:25 -0300 |
| commit | 58dbe934a90c1eda8e76cd218a413f01a4d9b11d (patch) | |
| tree | deaee88adad3791c8f010db7f7161a95318ed67e /cepis/models.lua | |
| parent | 7fd555fcaf4304cb0dff3e8f5661565c3618299e (diff) | |
| download | lua-0.2.0.tar.gz | |
A CEP that fails is rarely a random number: it is someone who knows the
city and guessed the digits, and the classic guess is the -000 that 957
municipalities never received. The API now answers that 404 with an
optional faixa block naming where the CEP would have been, so a caller
can turn "CEP does not exist" into something the user can act on.
It hangs off the error, never off an address: the lookup still failed.
Parsing gives up quietly at every step — no block, a block that is not
an object, one without a municipality to name — because a broken piece
of context must not turn a clean not-found into a parse failure.
cep_ini and cep_fim are the CEPs that exist, not the range the Correios
publish, and the interval between them is sparse; ceps is what keeps the
pair from being read as a list of valid CEPs.
Diffstat (limited to 'cepis/models.lua')
| -rw-r--r-- | cepis/models.lua | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/cepis/models.lua b/cepis/models.lua index 61ad678..a433369 100644 --- a/cepis/models.lua +++ b/cepis/models.lua @@ -185,6 +185,92 @@ function M.new_address(data) return address end +--- The municipality a CEP that does not exist would have belonged to. +-- +-- This is **context for an error, never an address**. It arrives on the 404 of +-- `Client:lookup` and hangs off the `not_found` error as `err.faixa`; the +-- lookup still failed, and nothing here says otherwise. The CEP asked for does +-- not exist. What the API is saying is only *where it would have been*. +-- +-- It exists because a CEP that fails is rarely a random number: it is usually +-- someone who knows the city and guessed the digits, and the classic guess is +-- the `-000` that 957 municipalities never received. Knowing the guess landed +-- on Areal/RJ turns "CEP does not exist" into a message the user can act on. +-- +-- **`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 range starts at `25845000`, which is precisely the CEP +-- that just failed; the range reported here starts at `25845001`, the first +-- one really in the base. +-- +-- **The range is sparse.** Areal's 118 CEPs are spread over the roughly 4,900 +-- numbers between `25845001` and `25849899`. That is what `ceps` is for: the +-- pair is an interval, never a list of valid CEPs, and picking a number +-- between them has about one chance in forty of existing. +-- +-- @type Faixa +-- @field localidade string the municipality +-- @field uf string +-- @field estado string +-- @field regiao string +-- @field ibge string +-- @field cep_ini string smallest CEP that exists there, 8 digits +-- @field cep_fim string largest CEP that exists there, 8 digits +-- @field ceps number how many exist between the two — far fewer than the span +local Faixa = {} +Faixa.__index = Faixa +Faixa.__name = "cepis.Faixa" + +--- The municipality and its UF: `Areal/RJ`. +-- +-- The one-line form for a message shown to a person, so it does not become a +-- repeated concatenation in every project that uses this. +-- @treturn string +function Faixa:label() + if self.uf == "" then + return self.localidade + end + return self.localidade .. "/" .. self.uf +end + +M.Faixa = Faixa + +--- Build a `Faixa` from the `faixa` block of a 404 body, or return `nil`. +-- +-- The API **omits** the block, never sends it as null, when the CEP falls in a +-- band no municipality owns. So `nil` here is the ordinary case, not a +-- failure. +-- +-- Anything unusable — absent, not an object, without a municipality to name — +-- is also `nil`. That is deliberate and it is the whole point of this +-- function: the caller is already holding a not-found, and a malformed piece +-- of context must never be allowed to turn that clean answer into a parse +-- error. +-- +-- @tparam[opt] table block the decoded `faixa` object +-- @treturn Faixa|nil +function M.new_faixa(block) + if type(block) ~= "table" then + return nil + end + + local localidade = text(block.localidade) + if localidade == "" then + return nil + end + + return setmetatable({ + localidade = localidade, + uf = text(block.uf), + estado = text(block.estado), + regiao = text(block.regiao), + ibge = text(block.ibge), + cep_ini = text(block.cep_ini), + cep_fim = text(block.cep_fim), + ceps = integer(block.ceps), + }, Faixa) +end + --- The response of `GET /health`. -- -- Good for two things: checking that the API answers, and knowing **which |