diff options
Diffstat (limited to 'models.go')
| -rw-r--r-- | models.go | 47 |
1 files changed, 47 insertions, 0 deletions
@@ -35,6 +35,33 @@ func (g Geo) IsPrecise() bool { return g.Precisao == "logradouro" } +// Faixa is the municipality a CEP that does not exist would belong to, and the +// range of CEPs that municipality actually has. It arrives on the 404, hanging +// off [Error.Faixa]. +// +// A CEP that fails is rarely a random number. It is usually someone who knows +// the city and guessed the rest, and the classic guess is the "-000": a small +// town often has a single city-wide CEP ending that way, but 957 municipalities +// are coded street by street and never got one. Areal/RJ answers from +// 25845-001 up, never at 25845-000 — so the 404 for 25845000 names Areal. +// +// CEPIni and CEPFim are the smallest and the largest CEP that EXIST in that +// municipality, not the bounds the Correios publish. Do not read the pair as a +// list of valid CEPs: the range is sparse, which is what CEPs is for — Areal's +// 118 CEPs are scattered across nearly five thousand numbers. +type Faixa struct { + Localidade string `json:"localidade"` + UF string `json:"uf"` + Estado string `json:"estado"` + Regiao string `json:"regiao"` + IBGE string `json:"ibge"` + CEPIni string `json:"cep_ini"` + CEPFim string `json:"cep_fim"` + + // CEPs is how many CEPs the municipality actually has inside the range. + CEPs int `json:"ceps"` +} + // Address is a CEP and everything the database knows about it. // // The field names are the API's own, in Portuguese, with only the casing @@ -147,6 +174,26 @@ func decodeGeo(block json.RawMessage) *Geo { } } +// decodeFaixa reads the `faixa` block of a 404 body. Every failure — absent +// block, malformed JSON, a `faixa` without a locality — yields nil: the field +// is an extra on top of an error that is already complete without it, and it +// must never turn a clean ErrCEPNotFound into a parse failure. +func decodeFaixa(body []byte) *Faixa { + if len(body) == 0 { + return nil + } + var envelope struct { + Faixa *Faixa `json:"faixa"` + } + if err := json.Unmarshal(body, &envelope); err != nil { + return nil + } + if envelope.Faixa == nil || envelope.Faixa.Localidade == "" { + return nil + } + return envelope.Faixa +} + func rawString(value json.RawMessage) string { if len(value) == 0 { return "" |