1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
using System.Text.Json.Serialization;
namespace Cepis;
/// <summary>
/// The municipality a CEP that does not exist would have belonged to.
/// </summary>
/// <remarks>
/// <para>
/// This is <b>context for an error, never an address</b>. It rides on the 404
/// of <see cref="CepisClient.LookupAsync(string, CancellationToken)"/>, hanging
/// off <see cref="CepNotFoundException.Faixa"/>. The CEP that was asked for
/// still does not exist, and nothing here says otherwise: filling a form from
/// these fields would be inventing an address.
/// </para>
/// <para>
/// It is worth having because a CEP that fails is rarely random — it is usually
/// someone who knows the city and guessed the number. The classic guess is the
/// <c>-000</c>, which 957 municipalities never received. Knowing where the
/// guess landed is what turns "CEP not found" into "did you mean a street in
/// Areal/RJ?".
/// </para>
/// <para>
/// <see cref="CepIni"/> and <see cref="CepFim"/> are the smallest and the
/// largest CEP that <b>actually exist</b> in that municipality, <i>not</i> the
/// bounds the Correios publish. For Areal the DNE's own range starts at
/// <c>25845000</c> — exactly the CEP that just failed — while
/// <see cref="CepIni"/> is <c>25845001</c>.
/// </para>
/// <para>
/// The range is <b>sparse</b>, and the pair is not a list of valid CEPs. Areal
/// has 118 of them (<see cref="Ceps"/>) spread across the ~4,900 numbers
/// between its two ends, so a number picked in between overwhelmingly does not
/// exist either. Never iterate the interval, and never show it as a set of
/// usable CEPs.
/// </para>
/// <para>
/// The property names are the API's own, in Portuguese, with only the casing
/// adapted — the same rule the rest of the data follows. On the wire they are
/// <c>localidade</c>, <c>uf</c>, <c>estado</c>, <c>regiao</c>, <c>ibge</c>,
/// <c>cep_ini</c>, <c>cep_fim</c> and <c>ceps</c>.
/// </para>
/// </remarks>
public sealed record Faixa
{
/// <summary>The municipality. Wire name <c>localidade</c>.</summary>
[JsonPropertyName("localidade")]
public string Localidade { get; init; } = "";
/// <summary>The two-letter state code. Wire name <c>uf</c>.</summary>
[JsonPropertyName("uf")]
public string UF { get; init; } = "";
/// <summary>The state's name. Wire name <c>estado</c>.</summary>
[JsonPropertyName("estado")]
public string Estado { get; init; } = "";
/// <summary>The region of the country. Wire name <c>regiao</c>.</summary>
[JsonPropertyName("regiao")]
public string Regiao { get; init; } = "";
/// <summary>The IBGE municipality code. Wire name <c>ibge</c>.</summary>
[JsonPropertyName("ibge")]
public string Ibge { get; init; } = "";
/// <summary>
/// The smallest CEP that exists in that municipality, unmasked. Wire name
/// <c>cep_ini</c>.
/// </summary>
/// <remarks>
/// The smallest one <i>in the database</i>, not the start of the range the
/// Correios publish — the published start may itself be a CEP that was never
/// issued, which is often precisely the one the caller just tried.
/// </remarks>
[JsonPropertyName("cep_ini")]
public string CepIni { get; init; } = "";
/// <summary>
/// The largest CEP that exists in that municipality, unmasked. Wire name
/// <c>cep_fim</c>.
/// </summary>
/// <remarks>
/// Together with <see cref="CepIni"/> it bounds the CEPs of the
/// municipality; it does not enumerate them. See <see cref="Ceps"/>.
/// </remarks>
[JsonPropertyName("cep_fim")]
public string CepFim { get; init; } = "";
/// <summary>
/// How many CEPs the municipality actually has. Wire name <c>ceps</c>.
/// </summary>
/// <remarks>
/// This field exists to keep <see cref="CepIni"/> and <see cref="CepFim"/>
/// from being read as a contiguous interval. Areal's 118 CEPs sit inside a
/// span of about 4,900 numbers: the range is mostly empty.
/// </remarks>
[JsonPropertyName("ceps")]
public int Ceps { get; init; }
}
|